linux-fsdevel.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
* [PATCHv3 00/19] arm64: invoke syscalls with pt_regs
@ 2018-06-18 12:02 Mark Rutland
  2018-06-18 12:02 ` [PATCHv3 01/19] arm64: consistently use unsigned long for thread flags Mark Rutland
                   ` (19 more replies)
  0 siblings, 20 replies; 53+ messages in thread
From: Mark Rutland @ 2018-06-18 12:02 UTC (permalink / raw)
  To: linux-arm-kernel, catalin.marinas, will.deacon
  Cc: dave.martin, hch, james.morse, linux, linux-fsdevel,
	marc.zyngier, mark.rutland, viro

This series reworks arm64's syscall handling to minimize the propagation
of user-controlled register values into speculated code paths. As with
x86 [1], a wrapper is generated for each syscall, which extracts the
argument from a struct pt_regs. During kernel entry from userspace,
registers are zeroed.

The arm64 kernel code directly invokes some syscalls which the x86 code
doesn't, so I've added ksys_* wrappers for these, following the x86
example. The rest of the series is arm64-specific.

I've pushed the series out to my arm64/syscall-regs branch [2] on
kernel.org.

Since v1 [3]:
* Rebase atop of arm64 for-next/core (for SSBD conflicts)
* Move ksys_personality logic into <linux/syscalls.h>
* Move kcompat_sys_* wrappers to <linux/compat.h>
* Fix scno bounds check to use unsigned comparison
* Fix sve_user_reset() call in el0_svc_handler()
* Add BUILD_BUG() to the !CONFIG_ARM64_SVE stubs
* Accumulate acked-by / reviewed-by tags

Since v2 [4]:
* Rebase to v4.18-rc1
* Take upper 32 RES0 bits of SCTLR_ELx into account
* Accumulate acks

Thanks,
Mark.

[1] https://lkml.kernel.org/r/20180330093720.6780-1-linux@dominikbrodowski.net
[2] git://git.kernel.org/pub/scm/linux/kernel/git/mark/linux.git
[3] https://lkml.kernel.org/r/20180514094640.27569-1-mark.rutland@arm.com
[4] https://lkml.kernel.org/r/20180601112441.37810-1-mark.rutland@arm.com

Mark Rutland (19):
  arm64: consistently use unsigned long for thread flags
  arm64: move SCTLR_EL{1,2} assertions to <asm/sysreg.h>
  arm64: introduce sysreg_clear_set()
  arm64: kill config_sctlr_el1()
  arm64: kill change_cpacr()
  arm64: move sve_user_{enable,disable} to <asm/fpsimd.h>
  arm64: remove sigreturn wrappers
  arm64: convert raw syscall invocation to C
  arm64: convert syscall trace logic to C
  arm64: convert native/compat syscall entry to C
  arm64: don't reload GPRs after apply_ssbd
  arm64: zero GPRs upon entry from EL0
  kernel: add ksys_personality()
  kernel: add kcompat_sys_{f,}statfs64()
  arm64: remove in-kernel call to sys_personality()
  arm64: use {COMPAT,}SYSCALL_DEFINE0 for sigreturn
  arm64: use SYSCALL_DEFINE6() for mmap
  arm64: convert compat wrappers to C
  arm64: implement syscall wrappers

 arch/arm64/Kconfig                       |   1 +
 arch/arm64/include/asm/fpsimd.h          |  17 +++-
 arch/arm64/include/asm/syscall_wrapper.h |  80 +++++++++++++++++
 arch/arm64/include/asm/sysreg.h          |  39 +++++----
 arch/arm64/include/asm/unistd32.h        |  26 +++---
 arch/arm64/kernel/Makefile               |   5 +-
 arch/arm64/kernel/armv8_deprecated.c     |   8 +-
 arch/arm64/kernel/cpu_errata.c           |   3 +-
 arch/arm64/kernel/entry.S                | 145 ++++---------------------------
 arch/arm64/kernel/entry32.S              | 121 --------------------------
 arch/arm64/kernel/fpsimd.c               |  19 ----
 arch/arm64/kernel/signal.c               |   5 +-
 arch/arm64/kernel/signal32.c             |   6 +-
 arch/arm64/kernel/sys.c                  |  19 ++--
 arch/arm64/kernel/sys32.c                | 127 ++++++++++++++++++++++++---
 arch/arm64/kernel/syscall.c              | 114 ++++++++++++++++++++++++
 arch/arm64/kernel/traps.c                |   4 +-
 arch/arm64/mm/fault.c                    |   2 +-
 fs/statfs.c                              |  14 ++-
 include/linux/compat.h                   |  11 +++
 include/linux/syscalls.h                 |  11 +++
 21 files changed, 441 insertions(+), 336 deletions(-)
 create mode 100644 arch/arm64/include/asm/syscall_wrapper.h
 delete mode 100644 arch/arm64/kernel/entry32.S
 create mode 100644 arch/arm64/kernel/syscall.c

-- 
2.11.0

^ permalink raw reply	[flat|nested] 53+ messages in thread

* [PATCHv3 01/19] arm64: consistently use unsigned long for thread flags
  2018-06-18 12:02 [PATCHv3 00/19] arm64: invoke syscalls with pt_regs Mark Rutland
@ 2018-06-18 12:02 ` Mark Rutland
  2018-06-19 10:49   ` Catalin Marinas
  2018-06-18 12:02 ` [PATCHv3 02/19] arm64: move SCTLR_EL{1,2} assertions to <asm/sysreg.h> Mark Rutland
                   ` (18 subsequent siblings)
  19 siblings, 1 reply; 53+ messages in thread
From: Mark Rutland @ 2018-06-18 12:02 UTC (permalink / raw)
  To: linux-arm-kernel, catalin.marinas, will.deacon
  Cc: dave.martin, hch, james.morse, linux, linux-fsdevel,
	marc.zyngier, mark.rutland, viro

In do_notify_resume, we manipulate thread_flags as a 32-bit unsigned
int, whereas thread_info::flags is a 64-bit unsigned long, and elsewhere
(e.g. in the entry assembly) we manipulate the flags as a 64-bit
quantity.

For consistency, and to avoid problems if we end up with more than 32
flags, let's make do_notify_resume take the flags as a 64-bit unsigned
long.

Signed-off-by: Mark Rutland <mark.rutland@arm.com>
Reviewed-by: Dave Martin <dave.martin@arm.com>
Cc: Catalin Marinas <catalin.marinas@arm.com>
Cc: Will Deacon <will.deacon@arm.com>
---
 arch/arm64/kernel/signal.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/arch/arm64/kernel/signal.c b/arch/arm64/kernel/signal.c
index 511af13e8d8f..70287634706e 100644
--- a/arch/arm64/kernel/signal.c
+++ b/arch/arm64/kernel/signal.c
@@ -910,7 +910,7 @@ static void do_signal(struct pt_regs *regs)
 }
 
 asmlinkage void do_notify_resume(struct pt_regs *regs,
-				 unsigned int thread_flags)
+				 unsigned long thread_flags)
 {
 	/*
 	 * The assembly code enters us with IRQs off, but it hasn't
-- 
2.11.0

^ permalink raw reply related	[flat|nested] 53+ messages in thread

* [PATCHv3 02/19] arm64: move SCTLR_EL{1,2} assertions to <asm/sysreg.h>
  2018-06-18 12:02 [PATCHv3 00/19] arm64: invoke syscalls with pt_regs Mark Rutland
  2018-06-18 12:02 ` [PATCHv3 01/19] arm64: consistently use unsigned long for thread flags Mark Rutland
@ 2018-06-18 12:02 ` Mark Rutland
  2018-06-19 11:02   ` [PATCHv3 02/19] arm64: move SCTLR_EL{1, 2} " Catalin Marinas
  2018-06-19 11:48   ` [PATCHv3 02/19] arm64: move SCTLR_EL{1,2} " Mark Rutland
  2018-06-18 12:02 ` [PATCHv3 03/19] arm64: introduce sysreg_clear_set() Mark Rutland
                   ` (17 subsequent siblings)
  19 siblings, 2 replies; 53+ messages in thread
From: Mark Rutland @ 2018-06-18 12:02 UTC (permalink / raw)
  To: linux-arm-kernel, catalin.marinas, will.deacon
  Cc: dave.martin, hch, james.morse, linux, linux-fsdevel,
	marc.zyngier, mark.rutland, viro

Currently we assert that the SCTLR_EL{1,2}_{SET,CLEAR} bits are
self-consistent with an assertion in config_sctlr_el1(). This is a bit
unusual, since config_sctlr_el1() doesn't make use of these definitions,
and is far away from the definitions themselves.

We can use the CPP #error directive to have equivalent assertions in
<asm/sysreg.h>, next to the definitions of the set/clear bits, which is
a bit clearer and simpler.

At the same time, lets fill in the upper 32 bits for both registers in
their repsective RES0 definitions. This could be a little nicer with
GENMASK_ULL(63, 32), but this currently lives in <linux/bitops.h>, which
cannot safely be included from assembly, as <asm/sysreg.h> can.

Note the when the preprocessor evaluates an expression for an #if
directive, all signed or unsigned values are treated as intmax_t or
uintmax_t respectively. To avoid ambiguity, we define explicitly define
the mask of all 64 bits.

Signed-off-by: Mark Rutland <mark.rutland@arm.com>
Cc: Catalin Marinas <catalin.marinas@arm.com>
Cc: Dave Martin <dave.martin@arm.com>
Cc: James Morse <james.morse@arm.com>
Cc: Will Deacon <will.deacon@arm.com>
---
 arch/arm64/include/asm/sysreg.h | 20 ++++++++++----------
 1 file changed, 10 insertions(+), 10 deletions(-)

diff --git a/arch/arm64/include/asm/sysreg.h b/arch/arm64/include/asm/sysreg.h
index 6171178075dc..48ad361c178e 100644
--- a/arch/arm64/include/asm/sysreg.h
+++ b/arch/arm64/include/asm/sysreg.h
@@ -436,7 +436,8 @@
 #define SCTLR_EL2_RES0	((1 << 6)  | (1 << 7)  | (1 << 8)  | (1 << 9)  | \
 			 (1 << 10) | (1 << 13) | (1 << 14) | (1 << 15) | \
 			 (1 << 17) | (1 << 20) | (1 << 24) | (1 << 26) | \
-			 (1 << 27) | (1 << 30) | (1 << 31))
+			 (1 << 27) | (1 << 30) | (1 << 31) | \
+			 (0xffffffffUL << 32))
 
 #ifdef CONFIG_CPU_BIG_ENDIAN
 #define ENDIAN_SET_EL2		SCTLR_ELx_EE
@@ -452,9 +453,9 @@
 			 SCTLR_ELx_SA     | SCTLR_ELx_I    | SCTLR_ELx_WXN | \
 			 ENDIAN_CLEAR_EL2 | SCTLR_EL2_RES0)
 
-/* Check all the bits are accounted for */
-#define SCTLR_EL2_BUILD_BUG_ON_MISSING_BITS	BUILD_BUG_ON((SCTLR_EL2_SET ^ SCTLR_EL2_CLEAR) != ~0)
-
+#if (SCTLR_EL2_SET ^ SCTLR_EL2_CLEAR) != 0xffffffffffffffff
+#error "Inconsistent SCTLR_EL2 set/clear bits"
+#endif
 
 /* SCTLR_EL1 specific flags. */
 #define SCTLR_EL1_UCI		(1 << 26)
@@ -473,7 +474,8 @@
 #define SCTLR_EL1_RES1	((1 << 11) | (1 << 20) | (1 << 22) | (1 << 28) | \
 			 (1 << 29))
 #define SCTLR_EL1_RES0  ((1 << 6)  | (1 << 10) | (1 << 13) | (1 << 17) | \
-			 (1 << 27) | (1 << 30) | (1 << 31))
+			 (1 << 27) | (1 << 30) | (1 << 31) | \
+			 (0xffffffffUL << 32))
 
 #ifdef CONFIG_CPU_BIG_ENDIAN
 #define ENDIAN_SET_EL1		(SCTLR_EL1_E0E | SCTLR_ELx_EE)
@@ -492,8 +494,9 @@
 			 SCTLR_EL1_UMA | SCTLR_ELx_WXN     | ENDIAN_CLEAR_EL1 |\
 			 SCTLR_EL1_RES0)
 
-/* Check all the bits are accounted for */
-#define SCTLR_EL1_BUILD_BUG_ON_MISSING_BITS	BUILD_BUG_ON((SCTLR_EL1_SET ^ SCTLR_EL1_CLEAR) != ~0)
+#if (SCTLR_EL1_SET ^ SCTLR_EL1_CLEAR) != 0xffffffffffffffff
+#error "Inconsistent SCTLR_EL1 set/clear bits"
+#endif
 
 /* id_aa64isar0 */
 #define ID_AA64ISAR0_TS_SHIFT		52
@@ -732,9 +735,6 @@ static inline void config_sctlr_el1(u32 clear, u32 set)
 {
 	u32 val;
 
-	SCTLR_EL2_BUILD_BUG_ON_MISSING_BITS;
-	SCTLR_EL1_BUILD_BUG_ON_MISSING_BITS;
-
 	val = read_sysreg(sctlr_el1);
 	val &= ~clear;
 	val |= set;
-- 
2.11.0

^ permalink raw reply related	[flat|nested] 53+ messages in thread

* [PATCHv3 03/19] arm64: introduce sysreg_clear_set()
  2018-06-18 12:02 [PATCHv3 00/19] arm64: invoke syscalls with pt_regs Mark Rutland
  2018-06-18 12:02 ` [PATCHv3 01/19] arm64: consistently use unsigned long for thread flags Mark Rutland
  2018-06-18 12:02 ` [PATCHv3 02/19] arm64: move SCTLR_EL{1,2} assertions to <asm/sysreg.h> Mark Rutland
@ 2018-06-18 12:02 ` Mark Rutland
  2018-06-19 11:44   ` Catalin Marinas
  2018-06-19 11:47   ` Marc Zyngier
  2018-06-18 12:02 ` [PATCHv3 04/19] arm64: kill config_sctlr_el1() Mark Rutland
                   ` (16 subsequent siblings)
  19 siblings, 2 replies; 53+ messages in thread
From: Mark Rutland @ 2018-06-18 12:02 UTC (permalink / raw)
  To: linux-arm-kernel, catalin.marinas, will.deacon
  Cc: dave.martin, hch, james.morse, linux, linux-fsdevel,
	marc.zyngier, mark.rutland, viro

Currently we have a couple of helpers to manipulate bits in particular
sysregs:

 * config_sctlr_el1(u32 clear, u32 set)

 * change_cpacr(u64 val, u64 mask)

The parameters of these differ in naming convention, order, and size,
which is unfortunate. They also differ slightly in behaviour, as
change_cpacr() skips the sysreg write if the bits are unchanged, which
is a useful optimization when sysreg writes are expensive.

Before we gain more yet another sysreg manipulation function, let's
unify these with a common helper, providing a consistent order for
clear/set operands, and the write skipping behaviour from
change_cpacr(). Code will be migrated to the new helper in subsequent
patches.

Signed-off-by: Mark Rutland <mark.rutland@arm.com>
Reviewed-by: Dave Martin <dave.martin@arm.com>
Cc: Catalin Marinas <catalin.marinas@arm.com>
Cc: Marc Zyngier <marc.zyngier@arm.com>
---
 arch/arm64/include/asm/sysreg.h | 11 +++++++++++
 1 file changed, 11 insertions(+)

diff --git a/arch/arm64/include/asm/sysreg.h b/arch/arm64/include/asm/sysreg.h
index 48ad361c178e..fefc17dae8ee 100644
--- a/arch/arm64/include/asm/sysreg.h
+++ b/arch/arm64/include/asm/sysreg.h
@@ -731,6 +731,17 @@ asm(
 	asm volatile("msr_s " __stringify(r) ", %x0" : : "rZ" (__val));	\
 } while (0)
 
+/*
+ * Modify bits in a sysreg. Bits in the clear mask are zeroed, then bits in the
+ * set mask are set. Other bits are left as-is.
+ */
+#define sysreg_clear_set(sysreg, clear, set) do {			\
+	u64 __scs_val = read_sysreg(sysreg);				\
+	u64 __scs_new = (__scs_val & ~(u64)(clear)) | (set);		\
+	if (__scs_new != __scs_val)					\
+		write_sysreg(__scs_new, sysreg);			\
+} while (0)
+
 static inline void config_sctlr_el1(u32 clear, u32 set)
 {
 	u32 val;
-- 
2.11.0

^ permalink raw reply related	[flat|nested] 53+ messages in thread

* [PATCHv3 04/19] arm64: kill config_sctlr_el1()
  2018-06-18 12:02 [PATCHv3 00/19] arm64: invoke syscalls with pt_regs Mark Rutland
                   ` (2 preceding siblings ...)
  2018-06-18 12:02 ` [PATCHv3 03/19] arm64: introduce sysreg_clear_set() Mark Rutland
@ 2018-06-18 12:02 ` Mark Rutland
  2018-06-19 11:44   ` Catalin Marinas
  2018-06-18 12:02 ` [PATCHv3 05/19] arm64: kill change_cpacr() Mark Rutland
                   ` (15 subsequent siblings)
  19 siblings, 1 reply; 53+ messages in thread
From: Mark Rutland @ 2018-06-18 12:02 UTC (permalink / raw)
  To: linux-arm-kernel, catalin.marinas, will.deacon
  Cc: dave.martin, hch, james.morse, linux, linux-fsdevel,
	marc.zyngier, mark.rutland, viro

Now that we have sysreg_clear_set(), we can consistently use this
instead of config_sctlr_el1().

Signed-off-by: Mark Rutland <mark.rutland@arm.com>
Reviewed-by: Dave Martin <dave.martin@arm.com>
Cc: Catalin Marinas <catalin.marinas@arm.com>
Cc: James Morse <james.morse@arm.com>
Cc: Will Deacon <will.deacon@arm.com>
---
 arch/arm64/include/asm/sysreg.h      | 10 ----------
 arch/arm64/kernel/armv8_deprecated.c |  8 ++++----
 arch/arm64/kernel/cpu_errata.c       |  3 +--
 arch/arm64/kernel/traps.c            |  2 +-
 arch/arm64/mm/fault.c                |  2 +-
 5 files changed, 7 insertions(+), 18 deletions(-)

diff --git a/arch/arm64/include/asm/sysreg.h b/arch/arm64/include/asm/sysreg.h
index fefc17dae8ee..e205ec8489e9 100644
--- a/arch/arm64/include/asm/sysreg.h
+++ b/arch/arm64/include/asm/sysreg.h
@@ -742,16 +742,6 @@ asm(
 		write_sysreg(__scs_new, sysreg);			\
 } while (0)
 
-static inline void config_sctlr_el1(u32 clear, u32 set)
-{
-	u32 val;
-
-	val = read_sysreg(sctlr_el1);
-	val &= ~clear;
-	val |= set;
-	write_sysreg(val, sctlr_el1);
-}
-
 #endif
 
 #endif	/* __ASM_SYSREG_H */
diff --git a/arch/arm64/kernel/armv8_deprecated.c b/arch/arm64/kernel/armv8_deprecated.c
index d4707abb2f16..d01c7fc0463c 100644
--- a/arch/arm64/kernel/armv8_deprecated.c
+++ b/arch/arm64/kernel/armv8_deprecated.c
@@ -511,9 +511,9 @@ static int cp15barrier_handler(struct pt_regs *regs, u32 instr)
 static int cp15_barrier_set_hw_mode(bool enable)
 {
 	if (enable)
-		config_sctlr_el1(0, SCTLR_EL1_CP15BEN);
+		sysreg_clear_set(sctlr_el1, 0, SCTLR_EL1_CP15BEN);
 	else
-		config_sctlr_el1(SCTLR_EL1_CP15BEN, 0);
+		sysreg_clear_set(sctlr_el1, SCTLR_EL1_CP15BEN, 0);
 	return 0;
 }
 
@@ -548,9 +548,9 @@ static int setend_set_hw_mode(bool enable)
 		return -EINVAL;
 
 	if (enable)
-		config_sctlr_el1(SCTLR_EL1_SED, 0);
+		sysreg_clear_set(sctlr_el1, SCTLR_EL1_SED, 0);
 	else
-		config_sctlr_el1(0, SCTLR_EL1_SED);
+		sysreg_clear_set(sctlr_el1, 0, SCTLR_EL1_SED);
 	return 0;
 }
 
diff --git a/arch/arm64/kernel/cpu_errata.c b/arch/arm64/kernel/cpu_errata.c
index 1d2b6d768efe..92128ea53102 100644
--- a/arch/arm64/kernel/cpu_errata.c
+++ b/arch/arm64/kernel/cpu_errata.c
@@ -76,8 +76,7 @@ has_mismatched_cache_line_size(const struct arm64_cpu_capabilities *entry,
 static void
 cpu_enable_trap_ctr_access(const struct arm64_cpu_capabilities *__unused)
 {
-	/* Clear SCTLR_EL1.UCT */
-	config_sctlr_el1(SCTLR_EL1_UCT, 0);
+	sysreg_clear_set(sctlr_el1, SCTLR_EL1_UCT, 0);
 }
 
 atomic_t arm64_el2_vector_last_slot = ATOMIC_INIT(-1);
diff --git a/arch/arm64/kernel/traps.c b/arch/arm64/kernel/traps.c
index d399d459397b..c27292703bd1 100644
--- a/arch/arm64/kernel/traps.c
+++ b/arch/arm64/kernel/traps.c
@@ -411,7 +411,7 @@ asmlinkage void __exception do_undefinstr(struct pt_regs *regs)
 
 void cpu_enable_cache_maint_trap(const struct arm64_cpu_capabilities *__unused)
 {
-	config_sctlr_el1(SCTLR_EL1_UCI, 0);
+	sysreg_clear_set(sctlr_el1, SCTLR_EL1_UCI, 0);
 }
 
 #define __user_cache_maint(insn, address, res)			\
diff --git a/arch/arm64/mm/fault.c b/arch/arm64/mm/fault.c
index b8eecc7b9531..ea591c9e5144 100644
--- a/arch/arm64/mm/fault.c
+++ b/arch/arm64/mm/fault.c
@@ -879,7 +879,7 @@ void cpu_enable_pan(const struct arm64_cpu_capabilities *__unused)
 	 */
 	WARN_ON_ONCE(in_interrupt());
 
-	config_sctlr_el1(SCTLR_EL1_SPAN, 0);
+	sysreg_clear_set(sctlr_el1, SCTLR_EL1_SPAN, 0);
 	asm(SET_PSTATE_PAN(1));
 }
 #endif /* CONFIG_ARM64_PAN */
-- 
2.11.0

^ permalink raw reply related	[flat|nested] 53+ messages in thread

* [PATCHv3 05/19] arm64: kill change_cpacr()
  2018-06-18 12:02 [PATCHv3 00/19] arm64: invoke syscalls with pt_regs Mark Rutland
                   ` (3 preceding siblings ...)
  2018-06-18 12:02 ` [PATCHv3 04/19] arm64: kill config_sctlr_el1() Mark Rutland
@ 2018-06-18 12:02 ` Mark Rutland
  2018-06-19 11:45   ` Catalin Marinas
  2018-06-18 12:02 ` [PATCHv3 06/19] arm64: move sve_user_{enable,disable} to <asm/fpsimd.h> Mark Rutland
                   ` (14 subsequent siblings)
  19 siblings, 1 reply; 53+ messages in thread
From: Mark Rutland @ 2018-06-18 12:02 UTC (permalink / raw)
  To: linux-arm-kernel, catalin.marinas, will.deacon
  Cc: dave.martin, hch, james.morse, linux, linux-fsdevel,
	marc.zyngier, mark.rutland, viro

Now that we have sysreg_clear_set(), we can use this instead of
change_cpacr().

Note that the order of the set and clear arguments differs between
change_cpacr() and sysreg_clear_set(), so these are flipped as part of
the conversion. Also, sve_user_enable() redundantly clears
CPACR_EL1_ZEN_EL0EN before setting it; this is removed for clarity.

Signed-off-by: Mark Rutland <mark.rutland@arm.com>
Reviewed-by: Dave Martin <dave.martin@arm.com>
Cc: Catalin Marinas <catalin.marinas@arm.com>
Cc: James Morse <james.morse@arm.com>
Cc: Will Deacon <will.deacon@arm.com>
---
 arch/arm64/kernel/fpsimd.c | 13 ++-----------
 1 file changed, 2 insertions(+), 11 deletions(-)

diff --git a/arch/arm64/kernel/fpsimd.c b/arch/arm64/kernel/fpsimd.c
index 84c68b14f1b2..a98a7f96aff1 100644
--- a/arch/arm64/kernel/fpsimd.c
+++ b/arch/arm64/kernel/fpsimd.c
@@ -159,23 +159,14 @@ static void sve_free(struct task_struct *task)
 	__sve_free(task);
 }
 
-static void change_cpacr(u64 val, u64 mask)
-{
-	u64 cpacr = read_sysreg(CPACR_EL1);
-	u64 new = (cpacr & ~mask) | val;
-
-	if (new != cpacr)
-		write_sysreg(new, CPACR_EL1);
-}
-
 static void sve_user_disable(void)
 {
-	change_cpacr(0, CPACR_EL1_ZEN_EL0EN);
+	sysreg_clear_set(cpacr_el1, CPACR_EL1_ZEN_EL0EN, 0);
 }
 
 static void sve_user_enable(void)
 {
-	change_cpacr(CPACR_EL1_ZEN_EL0EN, CPACR_EL1_ZEN_EL0EN);
+	sysreg_clear_set(cpacr_el1, 0, CPACR_EL1_ZEN_EL0EN);
 }
 
 /*
-- 
2.11.0

^ permalink raw reply related	[flat|nested] 53+ messages in thread

* [PATCHv3 06/19] arm64: move sve_user_{enable,disable} to <asm/fpsimd.h>
  2018-06-18 12:02 [PATCHv3 00/19] arm64: invoke syscalls with pt_regs Mark Rutland
                   ` (4 preceding siblings ...)
  2018-06-18 12:02 ` [PATCHv3 05/19] arm64: kill change_cpacr() Mark Rutland
@ 2018-06-18 12:02 ` Mark Rutland
  2018-06-19 12:00   ` [PATCHv3 06/19] arm64: move sve_user_{enable, disable} " Catalin Marinas
  2018-06-19 12:19   ` Dave Martin
  2018-06-18 12:02 ` [PATCHv3 07/19] arm64: remove sigreturn wrappers Mark Rutland
                   ` (13 subsequent siblings)
  19 siblings, 2 replies; 53+ messages in thread
From: Mark Rutland @ 2018-06-18 12:02 UTC (permalink / raw)
  To: linux-arm-kernel, catalin.marinas, will.deacon
  Cc: dave.martin, hch, james.morse, linux, linux-fsdevel,
	marc.zyngier, mark.rutland, viro

In subsequent patches, we'll want to make use of sve_user_enable() and
sve_user_disable() outside of kernel/fpsimd.c. Let's move these to
<asm/fpsimd.h> where we can make use of them.

To avoid ifdeffery in sequences like:

if (system_supports_sve() && some_condition
	sve_user_disable();

... empty stubs are provided when support for SVE is not enabled. Note
that system_supports_sve() contains as IS_ENABLED(CONFIG_ARM64_SVE), so
the sve_user_disable() call should be optimized away entirely when
CONFIG_ARM64_SVE is not selected.

To ensure that this is the case, the stub definitions contain a
BUILD_BUG(), as we do for other stubs for which calls should always be
optimized away when the relevant config option is not selected.

At the same time, the include list of <asm/fpsimd.h> is sorted while
adding <asm/sysreg.h>.

Signed-off-by: Mark Rutland <mark.rutland@arm.com>
Cc: Catalin Marinas <catalin.marinas@arm.com>
Cc: Dave Martin <dave.martin@arm.com>
Cc: Will Deacon <will.deacon@arm.com>
---
 arch/arm64/include/asm/fpsimd.h | 17 ++++++++++++++++-
 arch/arm64/kernel/fpsimd.c      | 10 ----------
 2 files changed, 16 insertions(+), 11 deletions(-)

diff --git a/arch/arm64/include/asm/fpsimd.h b/arch/arm64/include/asm/fpsimd.h
index fa92747a49c8..dd1ad3950ef5 100644
--- a/arch/arm64/include/asm/fpsimd.h
+++ b/arch/arm64/include/asm/fpsimd.h
@@ -16,13 +16,15 @@
 #ifndef __ASM_FP_H
 #define __ASM_FP_H
 
-#include <asm/ptrace.h>
 #include <asm/errno.h>
+#include <asm/ptrace.h>
 #include <asm/processor.h>
 #include <asm/sigcontext.h>
+#include <asm/sysreg.h>
 
 #ifndef __ASSEMBLY__
 
+#include <linux/build_bug.h>
 #include <linux/cache.h>
 #include <linux/init.h>
 #include <linux/stddef.h>
@@ -102,6 +104,16 @@ extern int sve_set_vector_length(struct task_struct *task,
 extern int sve_set_current_vl(unsigned long arg);
 extern int sve_get_current_vl(void);
 
+static inline void sve_user_disable(void)
+{
+	sysreg_clear_set(cpacr_el1, CPACR_EL1_ZEN_EL0EN, 0);
+}
+
+static inline void sve_user_enable(void)
+{
+	sysreg_clear_set(cpacr_el1, 0, CPACR_EL1_ZEN_EL0EN);
+}
+
 /*
  * Probing and setup functions.
  * Calls to these functions must be serialised with one another.
@@ -128,6 +140,9 @@ static inline int sve_get_current_vl(void)
 	return -EINVAL;
 }
 
+static inline void sve_user_disable(void) { BUILD_BUG(); }
+static inline void sve_user_enable(void) { BUILD_BUG(); }
+
 static inline void sve_init_vq_map(void) { }
 static inline void sve_update_vq_map(void) { }
 static inline int sve_verify_vq_map(void) { return 0; }
diff --git a/arch/arm64/kernel/fpsimd.c b/arch/arm64/kernel/fpsimd.c
index a98a7f96aff1..58c53bc96928 100644
--- a/arch/arm64/kernel/fpsimd.c
+++ b/arch/arm64/kernel/fpsimd.c
@@ -159,16 +159,6 @@ static void sve_free(struct task_struct *task)
 	__sve_free(task);
 }
 
-static void sve_user_disable(void)
-{
-	sysreg_clear_set(cpacr_el1, CPACR_EL1_ZEN_EL0EN, 0);
-}
-
-static void sve_user_enable(void)
-{
-	sysreg_clear_set(cpacr_el1, 0, CPACR_EL1_ZEN_EL0EN);
-}
-
 /*
  * TIF_SVE controls whether a task can use SVE without trapping while
  * in userspace, and also the way a task's FPSIMD/SVE state is stored
-- 
2.11.0

^ permalink raw reply related	[flat|nested] 53+ messages in thread

* [PATCHv3 07/19] arm64: remove sigreturn wrappers
  2018-06-18 12:02 [PATCHv3 00/19] arm64: invoke syscalls with pt_regs Mark Rutland
                   ` (5 preceding siblings ...)
  2018-06-18 12:02 ` [PATCHv3 06/19] arm64: move sve_user_{enable,disable} to <asm/fpsimd.h> Mark Rutland
@ 2018-06-18 12:02 ` Mark Rutland
  2018-06-19 12:47   ` Catalin Marinas
  2018-06-18 12:02 ` [PATCHv3 08/19] arm64: convert raw syscall invocation to C Mark Rutland
                   ` (12 subsequent siblings)
  19 siblings, 1 reply; 53+ messages in thread
From: Mark Rutland @ 2018-06-18 12:02 UTC (permalink / raw)
  To: linux-arm-kernel, catalin.marinas, will.deacon
  Cc: dave.martin, hch, james.morse, linux, linux-fsdevel,
	marc.zyngier, mark.rutland, viro

The arm64 sigreturn* syscall handlers are non-standard. Rather than
taking a number of user parameters in registers as per the AAPCS,
they expect the pt_regs as their sole argument.

To make this work, we override the syscall definitions to invoke
wrappers written in assembly, which mov the SP into x0, and branch to
their respective C functions.

On other architectures (such as x86), the sigreturn* functions take no
argument and instead use current_pt_regs() to acquire the user
registers. This requires less boilerplate code, and allows for other
features such as interposing C code in this path.

This patch takes the same approach for arm64.

Signed-off-by: Mark Rutland <mark.rutland@arm.com>
Tentatively-reviewed-by: Dave Martin <dave.martin@arm.com>
Cc: Catalin Marinas <catalin.marinas@arm.com>
Cc: Will Deacon <will.deacon@arm.com>
---
 arch/arm64/include/asm/unistd32.h |  4 ++--
 arch/arm64/kernel/entry.S         |  8 --------
 arch/arm64/kernel/entry32.S       | 10 ----------
 arch/arm64/kernel/signal.c        |  3 ++-
 arch/arm64/kernel/signal32.c      |  6 ++++--
 arch/arm64/kernel/sys.c           |  3 +--
 arch/arm64/kernel/sys32.c         |  4 ++--
 7 files changed, 11 insertions(+), 27 deletions(-)

diff --git a/arch/arm64/include/asm/unistd32.h b/arch/arm64/include/asm/unistd32.h
index ef292160748c..ab95554b1734 100644
--- a/arch/arm64/include/asm/unistd32.h
+++ b/arch/arm64/include/asm/unistd32.h
@@ -260,7 +260,7 @@ __SYSCALL(117, sys_ni_syscall)
 #define __NR_fsync 118
 __SYSCALL(__NR_fsync, sys_fsync)
 #define __NR_sigreturn 119
-__SYSCALL(__NR_sigreturn, compat_sys_sigreturn_wrapper)
+__SYSCALL(__NR_sigreturn, compat_sys_sigreturn)
 #define __NR_clone 120
 __SYSCALL(__NR_clone, sys_clone)
 #define __NR_setdomainname 121
@@ -368,7 +368,7 @@ __SYSCALL(__NR_getresgid, sys_getresgid16)
 #define __NR_prctl 172
 __SYSCALL(__NR_prctl, sys_prctl)
 #define __NR_rt_sigreturn 173
-__SYSCALL(__NR_rt_sigreturn, compat_sys_rt_sigreturn_wrapper)
+__SYSCALL(__NR_rt_sigreturn, compat_sys_rt_sigreturn)
 #define __NR_rt_sigaction 174
 __SYSCALL(__NR_rt_sigaction, compat_sys_rt_sigaction)
 #define __NR_rt_sigprocmask 175
diff --git a/arch/arm64/kernel/entry.S b/arch/arm64/kernel/entry.S
index 28ad8799406f..62f2876f9c63 100644
--- a/arch/arm64/kernel/entry.S
+++ b/arch/arm64/kernel/entry.S
@@ -1138,14 +1138,6 @@ __entry_tramp_data_start:
 #endif /* CONFIG_UNMAP_KERNEL_AT_EL0 */
 
 /*
- * Special system call wrappers.
- */
-ENTRY(sys_rt_sigreturn_wrapper)
-	mov	x0, sp
-	b	sys_rt_sigreturn
-ENDPROC(sys_rt_sigreturn_wrapper)
-
-/*
  * Register switch for AArch64. The callee-saved registers need to be saved
  * and restored. On entry:
  *   x0 = previous task_struct (must be preserved across the switch)
diff --git a/arch/arm64/kernel/entry32.S b/arch/arm64/kernel/entry32.S
index f332d5d1f6b4..f9461696dde4 100644
--- a/arch/arm64/kernel/entry32.S
+++ b/arch/arm64/kernel/entry32.S
@@ -30,16 +30,6 @@
  * System call wrappers for the AArch32 compatibility layer.
  */
 
-ENTRY(compat_sys_sigreturn_wrapper)
-	mov	x0, sp
-	b	compat_sys_sigreturn
-ENDPROC(compat_sys_sigreturn_wrapper)
-
-ENTRY(compat_sys_rt_sigreturn_wrapper)
-	mov	x0, sp
-	b	compat_sys_rt_sigreturn
-ENDPROC(compat_sys_rt_sigreturn_wrapper)
-
 ENTRY(compat_sys_statfs64_wrapper)
 	mov	w3, #84
 	cmp	w1, #88
diff --git a/arch/arm64/kernel/signal.c b/arch/arm64/kernel/signal.c
index 70287634706e..f03e664f773f 100644
--- a/arch/arm64/kernel/signal.c
+++ b/arch/arm64/kernel/signal.c
@@ -539,8 +539,9 @@ static int restore_sigframe(struct pt_regs *regs,
 	return err;
 }
 
-asmlinkage long sys_rt_sigreturn(struct pt_regs *regs)
+asmlinkage long sys_rt_sigreturn(void)
 {
+	struct pt_regs *regs = current_pt_regs();
 	struct rt_sigframe __user *frame;
 
 	/* Always make any pending restarted system calls return -EINTR */
diff --git a/arch/arm64/kernel/signal32.c b/arch/arm64/kernel/signal32.c
index 77b91f478995..cb10588a7cb2 100644
--- a/arch/arm64/kernel/signal32.c
+++ b/arch/arm64/kernel/signal32.c
@@ -282,8 +282,9 @@ static int compat_restore_sigframe(struct pt_regs *regs,
 	return err;
 }
 
-asmlinkage int compat_sys_sigreturn(struct pt_regs *regs)
+asmlinkage int compat_sys_sigreturn(void)
 {
+	struct pt_regs *regs = current_pt_regs();
 	struct compat_sigframe __user *frame;
 
 	/* Always make any pending restarted system calls return -EINTR */
@@ -312,8 +313,9 @@ asmlinkage int compat_sys_sigreturn(struct pt_regs *regs)
 	return 0;
 }
 
-asmlinkage int compat_sys_rt_sigreturn(struct pt_regs *regs)
+asmlinkage int compat_sys_rt_sigreturn(void)
 {
+	struct pt_regs *regs = current_pt_regs();
 	struct compat_rt_sigframe __user *frame;
 
 	/* Always make any pending restarted system calls return -EINTR */
diff --git a/arch/arm64/kernel/sys.c b/arch/arm64/kernel/sys.c
index 72981bae10eb..31045f3fed92 100644
--- a/arch/arm64/kernel/sys.c
+++ b/arch/arm64/kernel/sys.c
@@ -48,8 +48,7 @@ SYSCALL_DEFINE1(arm64_personality, unsigned int, personality)
 /*
  * Wrappers to pass the pt_regs argument.
  */
-asmlinkage long sys_rt_sigreturn_wrapper(void);
-#define sys_rt_sigreturn	sys_rt_sigreturn_wrapper
+asmlinkage long sys_rt_sigreturn(void);
 #define sys_personality		sys_arm64_personality
 
 #undef __SYSCALL
diff --git a/arch/arm64/kernel/sys32.c b/arch/arm64/kernel/sys32.c
index a40b1343b819..1ef103c95410 100644
--- a/arch/arm64/kernel/sys32.c
+++ b/arch/arm64/kernel/sys32.c
@@ -25,8 +25,8 @@
 #include <linux/compiler.h>
 #include <linux/syscalls.h>
 
-asmlinkage long compat_sys_sigreturn_wrapper(void);
-asmlinkage long compat_sys_rt_sigreturn_wrapper(void);
+asmlinkage long compat_sys_sigreturn(void);
+asmlinkage long compat_sys_rt_sigreturn(void);
 asmlinkage long compat_sys_statfs64_wrapper(void);
 asmlinkage long compat_sys_fstatfs64_wrapper(void);
 asmlinkage long compat_sys_pread64_wrapper(void);
-- 
2.11.0

^ permalink raw reply related	[flat|nested] 53+ messages in thread

* [PATCHv3 08/19] arm64: convert raw syscall invocation to C
  2018-06-18 12:02 [PATCHv3 00/19] arm64: invoke syscalls with pt_regs Mark Rutland
                   ` (6 preceding siblings ...)
  2018-06-18 12:02 ` [PATCHv3 07/19] arm64: remove sigreturn wrappers Mark Rutland
@ 2018-06-18 12:02 ` Mark Rutland
  2018-06-19 13:33   ` Catalin Marinas
  2018-06-19 14:21   ` Catalin Marinas
  2018-06-18 12:03 ` [PATCHv3 09/19] arm64: convert syscall trace logic " Mark Rutland
                   ` (11 subsequent siblings)
  19 siblings, 2 replies; 53+ messages in thread
From: Mark Rutland @ 2018-06-18 12:02 UTC (permalink / raw)
  To: linux-arm-kernel, catalin.marinas, will.deacon
  Cc: dave.martin, hch, james.morse, linux, linux-fsdevel,
	marc.zyngier, mark.rutland, viro

As a first step towards invoking syscalls with a pt_regs argument,
convert the raw syscall invocation logic to C. We end up with a bit more
register shuffling, but the unified invocation logic means we can unify
the tracing paths, too.

Previously, assembly had to open-code calls to ni_sys() when the system
call number was out-of-bounds for the relevant syscall table. This case
is now handled by invoke_syscall(), and the assembly no longer need to
handle this case explicitly. This allows the tracing paths to be
simplfiied and unified, as we no longer need the __ni_sys_trace path and
the __sys_trace_return label.

This only converts the invocation of the syscall. The rest of the
syscall triage and tracing is left in assembly for now, and will be
converted in subsequent patches.

Signed-off-by: Mark Rutland <mark.rutland@arm.com>
Cc: Catalin Marinas <catalin.marinas@arm.com>
Cc: Will Deacon <will.deacon@arm.com>
---
 arch/arm64/kernel/Makefile  |  3 ++-
 arch/arm64/kernel/entry.S   | 36 ++++++++++--------------------------
 arch/arm64/kernel/syscall.c | 30 ++++++++++++++++++++++++++++++
 3 files changed, 42 insertions(+), 27 deletions(-)
 create mode 100644 arch/arm64/kernel/syscall.c

diff --git a/arch/arm64/kernel/Makefile b/arch/arm64/kernel/Makefile
index 0025f8691046..4e24d2244bd1 100644
--- a/arch/arm64/kernel/Makefile
+++ b/arch/arm64/kernel/Makefile
@@ -18,7 +18,8 @@ arm64-obj-y		:= debug-monitors.o entry.o irq.o fpsimd.o		\
 			   hyp-stub.o psci.o cpu_ops.o insn.o	\
 			   return_address.o cpuinfo.o cpu_errata.o		\
 			   cpufeature.o alternative.o cacheinfo.o		\
-			   smp.o smp_spin_table.o topology.o smccc-call.o
+			   smp.o smp_spin_table.o topology.o smccc-call.o	\
+			   syscall.o
 
 extra-$(CONFIG_EFI)			:= efi-entry.o
 
diff --git a/arch/arm64/kernel/entry.S b/arch/arm64/kernel/entry.S
index 62f2876f9c63..c0392f78e392 100644
--- a/arch/arm64/kernel/entry.S
+++ b/arch/arm64/kernel/entry.S
@@ -903,7 +903,6 @@ ENDPROC(el0_error)
  */
 ret_fast_syscall:
 	disable_daif
-	str	x0, [sp, #S_X0]			// returned x0
 	ldr	x1, [tsk, #TSK_TI_FLAGS]	// re-check for syscall tracing
 	and	x2, x1, #_TIF_SYSCALL_WORK
 	cbnz	x2, ret_fast_syscall_trace
@@ -976,15 +975,11 @@ el0_svc_naked:					// compat entry point
 
 	tst	x16, #_TIF_SYSCALL_WORK		// check for syscall hooks
 	b.ne	__sys_trace
-	cmp     wscno, wsc_nr			// check upper syscall limit
-	b.hs	ni_sys
-	mask_nospec64 xscno, xsc_nr, x19	// enforce bounds for syscall number
-	ldr	x16, [stbl, xscno, lsl #3]	// address in the syscall table
-	blr	x16				// call sys_* routine
-	b	ret_fast_syscall
-ni_sys:
 	mov	x0, sp
-	bl	do_ni_syscall
+	mov	w1, wscno
+	mov	w2, wsc_nr
+	mov	x3, stbl
+	bl	invoke_syscall
 	b	ret_fast_syscall
 ENDPROC(el0_svc)
 
@@ -1001,29 +996,18 @@ __sys_trace:
 	bl	syscall_trace_enter
 	cmp	w0, #NO_SYSCALL			// skip the syscall?
 	b.eq	__sys_trace_return_skipped
-	mov	wscno, w0			// syscall number (possibly new)
-	mov	x1, sp				// pointer to regs
-	cmp	wscno, wsc_nr			// check upper syscall limit
-	b.hs	__ni_sys_trace
-	ldp	x0, x1, [sp]			// restore the syscall args
-	ldp	x2, x3, [sp, #S_X2]
-	ldp	x4, x5, [sp, #S_X4]
-	ldp	x6, x7, [sp, #S_X6]
-	ldr	x16, [stbl, xscno, lsl #3]	// address in the syscall table
-	blr	x16				// call sys_* routine
 
-__sys_trace_return:
-	str	x0, [sp, #S_X0]			// save returned x0
+	mov	x0, sp
+	mov	w1, wscno
+	mov	w2, wsc_nr
+	mov	x3, stbl
+	bl	invoke_syscall
+
 __sys_trace_return_skipped:
 	mov	x0, sp
 	bl	syscall_trace_exit
 	b	ret_to_user
 
-__ni_sys_trace:
-	mov	x0, sp
-	bl	do_ni_syscall
-	b	__sys_trace_return
-
 	.popsection				// .entry.text
 
 #ifdef CONFIG_UNMAP_KERNEL_AT_EL0
diff --git a/arch/arm64/kernel/syscall.c b/arch/arm64/kernel/syscall.c
new file mode 100644
index 000000000000..b463b962d597
--- /dev/null
+++ b/arch/arm64/kernel/syscall.c
@@ -0,0 +1,30 @@
+// SPDX-License-Identifier: GPL-2.0
+
+#include <linux/nospec.h>
+#include <linux/ptrace.h>
+
+long do_ni_syscall(struct pt_regs *regs);
+
+typedef long (*syscall_fn_t)(unsigned long, unsigned long,
+			     unsigned long, unsigned long,
+			     unsigned long, unsigned long);
+
+static void __invoke_syscall(struct pt_regs *regs, syscall_fn_t syscall_fn)
+{
+	regs->regs[0] = syscall_fn(regs->regs[0], regs->regs[1],
+				   regs->regs[2], regs->regs[3],
+				   regs->regs[4], regs->regs[5]);
+}
+
+asmlinkage void invoke_syscall(struct pt_regs *regs, unsigned int scno,
+			       unsigned int sc_nr,
+			       syscall_fn_t syscall_table[])
+{
+	if (scno < sc_nr) {
+		syscall_fn_t syscall_fn;
+		syscall_fn = syscall_table[array_index_nospec(scno, sc_nr)];
+		__invoke_syscall(regs, syscall_fn);
+	} else {
+		regs->regs[0] = do_ni_syscall(regs);
+	}
+}
-- 
2.11.0

^ permalink raw reply related	[flat|nested] 53+ messages in thread

* [PATCHv3 09/19] arm64: convert syscall trace logic to C
  2018-06-18 12:02 [PATCHv3 00/19] arm64: invoke syscalls with pt_regs Mark Rutland
                   ` (7 preceding siblings ...)
  2018-06-18 12:02 ` [PATCHv3 08/19] arm64: convert raw syscall invocation to C Mark Rutland
@ 2018-06-18 12:03 ` Mark Rutland
  2018-06-19 14:32   ` Catalin Marinas
  2018-06-18 12:03 ` [PATCHv3 10/19] arm64: convert native/compat syscall entry " Mark Rutland
                   ` (10 subsequent siblings)
  19 siblings, 1 reply; 53+ messages in thread
From: Mark Rutland @ 2018-06-18 12:03 UTC (permalink / raw)
  To: linux-arm-kernel, catalin.marinas, will.deacon
  Cc: dave.martin, hch, james.morse, linux, linux-fsdevel,
	marc.zyngier, mark.rutland, viro

Currently syscall tracing is a tricky assembly state machine, which can
be rather difficult to follow, and even harder to modify. Before we
start fiddling with it for pt_regs syscalls, let's convert it to C.

This is not intended to have any functional change.

Signed-off-by: Mark Rutland <mark.rutland@arm.com>
Cc: Catalin Marinas <catalin.marinas@arm.com>
Cc: Will Deacon <will.deacon@arm.com>
---
 arch/arm64/kernel/entry.S   | 53 ++---------------------------------------
 arch/arm64/kernel/syscall.c | 58 ++++++++++++++++++++++++++++++++++++++++++---
 2 files changed, 57 insertions(+), 54 deletions(-)

diff --git a/arch/arm64/kernel/entry.S b/arch/arm64/kernel/entry.S
index c0392f78e392..05b9f03f3e00 100644
--- a/arch/arm64/kernel/entry.S
+++ b/arch/arm64/kernel/entry.S
@@ -896,24 +896,6 @@ el0_error_naked:
 	b	ret_to_user
 ENDPROC(el0_error)
 
-
-/*
- * This is the fast syscall return path.  We do as little as possible here,
- * and this includes saving x0 back into the kernel stack.
- */
-ret_fast_syscall:
-	disable_daif
-	ldr	x1, [tsk, #TSK_TI_FLAGS]	// re-check for syscall tracing
-	and	x2, x1, #_TIF_SYSCALL_WORK
-	cbnz	x2, ret_fast_syscall_trace
-	and	x2, x1, #_TIF_WORK_MASK
-	cbnz	x2, work_pending
-	enable_step_tsk x1, x2
-	kernel_exit 0
-ret_fast_syscall_trace:
-	enable_daif
-	b	__sys_trace_return_skipped	// we already saved x0
-
 /*
  * Ok, we need to do extra processing, enter the slow path.
  */
@@ -969,44 +951,13 @@ alternative_else_nop_endif
 #endif
 
 el0_svc_naked:					// compat entry point
-	stp	x0, xscno, [sp, #S_ORIG_X0]	// save the original x0 and syscall number
-	enable_daif
-	ct_user_exit 1
-
-	tst	x16, #_TIF_SYSCALL_WORK		// check for syscall hooks
-	b.ne	__sys_trace
 	mov	x0, sp
 	mov	w1, wscno
 	mov	w2, wsc_nr
 	mov	x3, stbl
-	bl	invoke_syscall
-	b	ret_fast_syscall
-ENDPROC(el0_svc)
-
-	/*
-	 * This is the really slow path.  We're going to be doing context
-	 * switches, and waiting for our parent to respond.
-	 */
-__sys_trace:
-	cmp     wscno, #NO_SYSCALL		// user-issued syscall(-1)?
-	b.ne	1f
-	mov	x0, #-ENOSYS			// set default errno if so
-	str	x0, [sp, #S_X0]
-1:	mov	x0, sp
-	bl	syscall_trace_enter
-	cmp	w0, #NO_SYSCALL			// skip the syscall?
-	b.eq	__sys_trace_return_skipped
-
-	mov	x0, sp
-	mov	w1, wscno
-	mov	w2, wsc_nr
-	mov	x3, stbl
-	bl	invoke_syscall
-
-__sys_trace_return_skipped:
-	mov	x0, sp
-	bl	syscall_trace_exit
+	bl	el0_svc_common
 	b	ret_to_user
+ENDPROC(el0_svc)
 
 	.popsection				// .entry.text
 
diff --git a/arch/arm64/kernel/syscall.c b/arch/arm64/kernel/syscall.c
index b463b962d597..2adf1a073398 100644
--- a/arch/arm64/kernel/syscall.c
+++ b/arch/arm64/kernel/syscall.c
@@ -1,8 +1,13 @@
 // SPDX-License-Identifier: GPL-2.0
 
+#include <linux/compiler.h>
+#include <linux/context_tracking.h>
 #include <linux/nospec.h>
 #include <linux/ptrace.h>
 
+#include <asm/daifflags.h>
+#include <asm/thread_info.h>
+
 long do_ni_syscall(struct pt_regs *regs);
 
 typedef long (*syscall_fn_t)(unsigned long, unsigned long,
@@ -16,9 +21,9 @@ static void __invoke_syscall(struct pt_regs *regs, syscall_fn_t syscall_fn)
 				   regs->regs[4], regs->regs[5]);
 }
 
-asmlinkage void invoke_syscall(struct pt_regs *regs, unsigned int scno,
-			       unsigned int sc_nr,
-			       syscall_fn_t syscall_table[])
+static void invoke_syscall(struct pt_regs *regs, unsigned int scno,
+			   unsigned int sc_nr,
+			   syscall_fn_t syscall_table[])
 {
 	if (scno < sc_nr) {
 		syscall_fn_t syscall_fn;
@@ -28,3 +33,50 @@ asmlinkage void invoke_syscall(struct pt_regs *regs, unsigned int scno,
 		regs->regs[0] = do_ni_syscall(regs);
 	}
 }
+
+static inline bool has_syscall_work(unsigned long flags)
+{
+	return unlikely(flags & _TIF_SYSCALL_WORK);
+}
+
+int syscall_trace_enter(struct pt_regs *regs);
+void syscall_trace_exit(struct pt_regs *regs);
+
+asmlinkage void el0_svc_common(struct pt_regs *regs, int scno, int sc_nr,
+			       syscall_fn_t syscall_table[])
+{
+	unsigned long flags = current_thread_info()->flags;
+
+	regs->orig_x0 = regs->regs[0];
+	regs->syscallno = scno;
+
+	local_daif_restore(DAIF_PROCCTX);
+	user_exit();
+
+	if (has_syscall_work(flags)) {
+		/* set default errno for user-issued syscall(-1) */
+		if (scno == NO_SYSCALL)
+			regs->regs[0] = -ENOSYS;
+		scno = syscall_trace_enter(regs);
+		if (scno == NO_SYSCALL)
+			goto trace_exit;
+	}
+
+	invoke_syscall(regs, scno, sc_nr, syscall_table);
+
+	/*
+	 * The tracing status may have changed under our feet, so we have to
+	 * check again. However, if we were tracing entry, then we always trace
+	 * exit regardless, as the old entry assembly did.
+	 */
+	if (!has_syscall_work(flags)) {
+		local_daif_mask();
+		flags = current_thread_info()->flags;
+		if (!has_syscall_work(flags))
+			return;
+		local_daif_restore(DAIF_PROCCTX);
+	}
+
+trace_exit:
+	syscall_trace_exit(regs);
+}
-- 
2.11.0

^ permalink raw reply related	[flat|nested] 53+ messages in thread

* [PATCHv3 10/19] arm64: convert native/compat syscall entry to C
  2018-06-18 12:02 [PATCHv3 00/19] arm64: invoke syscalls with pt_regs Mark Rutland
                   ` (8 preceding siblings ...)
  2018-06-18 12:03 ` [PATCHv3 09/19] arm64: convert syscall trace logic " Mark Rutland
@ 2018-06-18 12:03 ` Mark Rutland
  2018-06-19 12:18   ` Dave Martin
  2018-06-19 15:20   ` Catalin Marinas
  2018-06-18 12:03 ` [PATCHv3 11/19] arm64: don't reload GPRs after apply_ssbd Mark Rutland
                   ` (9 subsequent siblings)
  19 siblings, 2 replies; 53+ messages in thread
From: Mark Rutland @ 2018-06-18 12:03 UTC (permalink / raw)
  To: linux-arm-kernel, catalin.marinas, will.deacon
  Cc: dave.martin, hch, james.morse, linux, linux-fsdevel,
	marc.zyngier, mark.rutland, viro

Now that the syscall invocation logic is in C, we can migrate the rest
of the syscall entry logic over, so that the entry assembly needn't look
at the register values at all.

The SVE reset across syscall logic now unconditionally clears TIF_SVE,
but sve_user_disable() will only write back to CPACR_EL1 when SVE is
actually enabled.

Signed-off-by: Mark Rutland <mark.rutland@arm.com>
Cc: Catalin Marinas <catalin.marinas@arm.com>
Cc: Will Deacon <will.deacon@arm.com>
---
 arch/arm64/kernel/entry.S   | 42 ++++--------------------------------------
 arch/arm64/kernel/syscall.c | 40 ++++++++++++++++++++++++++++++++++++++--
 2 files changed, 42 insertions(+), 40 deletions(-)

diff --git a/arch/arm64/kernel/entry.S b/arch/arm64/kernel/entry.S
index 05b9f03f3e00..156c4e3fd1a4 100644
--- a/arch/arm64/kernel/entry.S
+++ b/arch/arm64/kernel/entry.S
@@ -720,14 +720,9 @@ el0_sync_compat:
 	b.ge	el0_dbg
 	b	el0_inv
 el0_svc_compat:
-	/*
-	 * AArch32 syscall handling
-	 */
-	ldr	x16, [tsk, #TSK_TI_FLAGS]	// load thread flags
-	adrp	stbl, compat_sys_call_table	// load compat syscall table pointer
-	mov	wscno, w7			// syscall number in w7 (r7)
-	mov     wsc_nr, #__NR_compat_syscalls
-	b	el0_svc_naked
+	mov	x0, sp
+	bl	el0_svc_compat_handler
+	b	ret_to_user
 
 	.align	6
 el0_irq_compat:
@@ -925,37 +920,8 @@ ENDPROC(ret_to_user)
  */
 	.align	6
 el0_svc:
-	ldr	x16, [tsk, #TSK_TI_FLAGS]	// load thread flags
-	adrp	stbl, sys_call_table		// load syscall table pointer
-	mov	wscno, w8			// syscall number in w8
-	mov	wsc_nr, #__NR_syscalls
-
-#ifdef CONFIG_ARM64_SVE
-alternative_if_not ARM64_SVE
-	b	el0_svc_naked
-alternative_else_nop_endif
-	tbz	x16, #TIF_SVE, el0_svc_naked	// Skip unless TIF_SVE set:
-	bic	x16, x16, #_TIF_SVE		// discard SVE state
-	str	x16, [tsk, #TSK_TI_FLAGS]
-
-	/*
-	 * task_fpsimd_load() won't be called to update CPACR_EL1 in
-	 * ret_to_user unless TIF_FOREIGN_FPSTATE is still set, which only
-	 * happens if a context switch or kernel_neon_begin() or context
-	 * modification (sigreturn, ptrace) intervenes.
-	 * So, ensure that CPACR_EL1 is already correct for the fast-path case:
-	 */
-	mrs	x9, cpacr_el1
-	bic	x9, x9, #CPACR_EL1_ZEN_EL0EN	// disable SVE for el0
-	msr	cpacr_el1, x9			// synchronised by eret to el0
-#endif
-
-el0_svc_naked:					// compat entry point
 	mov	x0, sp
-	mov	w1, wscno
-	mov	w2, wsc_nr
-	mov	x3, stbl
-	bl	el0_svc_common
+	bl	el0_svc_handler
 	b	ret_to_user
 ENDPROC(el0_svc)
 
diff --git a/arch/arm64/kernel/syscall.c b/arch/arm64/kernel/syscall.c
index 2adf1a073398..6a31bb2a382b 100644
--- a/arch/arm64/kernel/syscall.c
+++ b/arch/arm64/kernel/syscall.c
@@ -6,7 +6,9 @@
 #include <linux/ptrace.h>
 
 #include <asm/daifflags.h>
+#include <asm/fpsimd.h>
 #include <asm/thread_info.h>
+#include <asm/unistd.h>
 
 long do_ni_syscall(struct pt_regs *regs);
 
@@ -42,8 +44,8 @@ static inline bool has_syscall_work(unsigned long flags)
 int syscall_trace_enter(struct pt_regs *regs);
 void syscall_trace_exit(struct pt_regs *regs);
 
-asmlinkage void el0_svc_common(struct pt_regs *regs, int scno, int sc_nr,
-			       syscall_fn_t syscall_table[])
+static void el0_svc_common(struct pt_regs *regs, int scno, int sc_nr,
+			   syscall_fn_t syscall_table[])
 {
 	unsigned long flags = current_thread_info()->flags;
 
@@ -80,3 +82,37 @@ asmlinkage void el0_svc_common(struct pt_regs *regs, int scno, int sc_nr,
 trace_exit:
 	syscall_trace_exit(regs);
 }
+
+static inline void sve_user_reset(void)
+{
+	if (!system_supports_sve())
+		return;
+
+	/*
+	 * task_fpsimd_load() won't be called to update CPACR_EL1 in
+	 * ret_to_user unless TIF_FOREIGN_FPSTATE is still set, which only
+	 * happens if a context switch or kernel_neon_begin() or context
+	 * modification (sigreturn, ptrace) intervenes.
+	 * So, ensure that CPACR_EL1 is already correct for the fast-path case.
+	 */
+	clear_thread_flag(TIF_SVE);
+	sve_user_disable();
+}
+
+extern syscall_fn_t sys_call_table[];
+
+asmlinkage void el0_svc_handler(struct pt_regs *regs)
+{
+	sve_user_reset();
+	el0_svc_common(regs, regs->regs[8], __NR_syscalls, sys_call_table);
+}
+
+#ifdef CONFIG_COMPAT
+extern syscall_fn_t compat_sys_call_table[];
+
+asmlinkage void el0_svc_compat_handler(struct pt_regs *regs)
+{
+	el0_svc_common(regs, regs->regs[7], __NR_compat_syscalls,
+		       compat_sys_call_table);
+}
+#endif
-- 
2.11.0

^ permalink raw reply related	[flat|nested] 53+ messages in thread

* [PATCHv3 11/19] arm64: don't reload GPRs after apply_ssbd
  2018-06-18 12:02 [PATCHv3 00/19] arm64: invoke syscalls with pt_regs Mark Rutland
                   ` (9 preceding siblings ...)
  2018-06-18 12:03 ` [PATCHv3 10/19] arm64: convert native/compat syscall entry " Mark Rutland
@ 2018-06-18 12:03 ` Mark Rutland
  2018-06-19 15:23   ` Catalin Marinas
  2018-06-18 12:03 ` [PATCHv3 12/19] arm64: zero GPRs upon entry from EL0 Mark Rutland
                   ` (8 subsequent siblings)
  19 siblings, 1 reply; 53+ messages in thread
From: Mark Rutland @ 2018-06-18 12:03 UTC (permalink / raw)
  To: linux-arm-kernel, catalin.marinas, will.deacon
  Cc: dave.martin, hch, james.morse, linux, linux-fsdevel,
	marc.zyngier, mark.rutland, viro

Now that all of the syscall logic works on the saved pt_regs, apply_ssbd
can safely corrupt x0-x3 in the entry paths, and we no longer need to
restore them. So let's remove the logic doing so.

With that logic gone, we can fold the branch target into the macro, so
that callers need not deal with this. GAS provides \@, which provides a
unique value per macro invocation, which we can use to create a unique
label.

Signed-off-by: Mark Rutland <mark.rutland@arm.com>
Acked-by: Marc Zyngier <marc.zyngier@arm.com>
Cc: Catalin Marinas <catalin.marinas@arm.com>
Cc: Will Deacon <will.deacon@arm.com>
---
 arch/arm64/kernel/entry.S | 20 +++++++-------------
 1 file changed, 7 insertions(+), 13 deletions(-)

diff --git a/arch/arm64/kernel/entry.S b/arch/arm64/kernel/entry.S
index 156c4e3fd1a4..22c58e7dfc0f 100644
--- a/arch/arm64/kernel/entry.S
+++ b/arch/arm64/kernel/entry.S
@@ -140,20 +140,21 @@ alternative_else_nop_endif
 
 	// This macro corrupts x0-x3. It is the caller's duty
 	// to save/restore them if required.
-	.macro	apply_ssbd, state, targ, tmp1, tmp2
+	.macro	apply_ssbd, state, tmp1, tmp2
 #ifdef CONFIG_ARM64_SSBD
 alternative_cb	arm64_enable_wa2_handling
-	b	\targ
+	b	skip_apply_ssbd\@
 alternative_cb_end
 	ldr_this_cpu	\tmp2, arm64_ssbd_callback_required, \tmp1
-	cbz	\tmp2, \targ
+	cbz	\tmp2, skip_apply_ssbd\@
 	ldr	\tmp2, [tsk, #TSK_TI_FLAGS]
-	tbnz	\tmp2, #TIF_SSBD, \targ
+	tbnz	\tmp2, #TIF_SSBD, skip_apply_ssbd\@
 	mov	w0, #ARM_SMCCC_ARCH_WORKAROUND_2
 	mov	w1, #\state
 alternative_cb	arm64_update_smccc_conduit
 	nop					// Patched to SMC/HVC #0
 alternative_cb_end
+skip_apply_ssbd\@:
 #endif
 	.endm
 
@@ -183,13 +184,7 @@ alternative_cb_end
 	ldr	x19, [tsk, #TSK_TI_FLAGS]	// since we can unmask debug
 	disable_step_tsk x19, x20		// exceptions when scheduling.
 
-	apply_ssbd 1, 1f, x22, x23
-
-#ifdef CONFIG_ARM64_SSBD
-	ldp	x0, x1, [sp, #16 * 0]
-	ldp	x2, x3, [sp, #16 * 1]
-#endif
-1:
+	apply_ssbd 1, x22, x23
 
 	mov	x29, xzr			// fp pointed to user-space
 	.else
@@ -331,8 +326,7 @@ alternative_if ARM64_WORKAROUND_845719
 alternative_else_nop_endif
 #endif
 3:
-	apply_ssbd 0, 5f, x0, x1
-5:
+	apply_ssbd 0, x0, x1
 	.endif
 
 	msr	elr_el1, x21			// set up the return data
-- 
2.11.0

^ permalink raw reply related	[flat|nested] 53+ messages in thread

* [PATCHv3 12/19] arm64: zero GPRs upon entry from EL0
  2018-06-18 12:02 [PATCHv3 00/19] arm64: invoke syscalls with pt_regs Mark Rutland
                   ` (10 preceding siblings ...)
  2018-06-18 12:03 ` [PATCHv3 11/19] arm64: don't reload GPRs after apply_ssbd Mark Rutland
@ 2018-06-18 12:03 ` Mark Rutland
  2018-06-19 15:24   ` Catalin Marinas
  2018-06-18 12:03 ` [PATCHv3 13/19] kernel: add ksys_personality() Mark Rutland
                   ` (7 subsequent siblings)
  19 siblings, 1 reply; 53+ messages in thread
From: Mark Rutland @ 2018-06-18 12:03 UTC (permalink / raw)
  To: linux-arm-kernel, catalin.marinas, will.deacon
  Cc: dave.martin, hch, james.morse, linux, linux-fsdevel,
	marc.zyngier, mark.rutland, viro

We can zero GPRs x0 - x29 upon entry from EL0 to make it harder for
userspace to control values consumed by speculative gadgets.

We don't blat x30, since this is stashed much later, and we'll blat it
before invoking C code.

Signed-off-by: Mark Rutland <mark.rutland@arm.com>
Cc: Catalin Marinas <catalin.marinas@arm.com>
Cc: Will Deacon <will.deacon@arm.com>
---
 arch/arm64/kernel/entry.S | 8 +++++++-
 1 file changed, 7 insertions(+), 1 deletion(-)

diff --git a/arch/arm64/kernel/entry.S b/arch/arm64/kernel/entry.S
index 22c58e7dfc0f..39440c2ee66d 100644
--- a/arch/arm64/kernel/entry.S
+++ b/arch/arm64/kernel/entry.S
@@ -63,6 +63,12 @@
 #endif
 	.endm
 
+	.macro	clear_gp_regs
+	.irp	n,0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29
+	mov	x\n, xzr
+	.endr
+	.endm
+
 /*
  * Bad Abort numbers
  *-----------------
@@ -179,6 +185,7 @@ skip_apply_ssbd\@:
 	stp	x28, x29, [sp, #16 * 14]
 
 	.if	\el == 0
+	clear_gp_regs
 	mrs	x21, sp_el0
 	ldr_this_cpu	tsk, __entry_task, x20	// Ensure MDSCR_EL1.SS is clear,
 	ldr	x19, [tsk, #TSK_TI_FLAGS]	// since we can unmask debug
@@ -186,7 +193,6 @@ skip_apply_ssbd\@:
 
 	apply_ssbd 1, x22, x23
 
-	mov	x29, xzr			// fp pointed to user-space
 	.else
 	add	x21, sp, #S_FRAME_SIZE
 	get_thread_info tsk
-- 
2.11.0

^ permalink raw reply related	[flat|nested] 53+ messages in thread

* [PATCHv3 13/19] kernel: add ksys_personality()
  2018-06-18 12:02 [PATCHv3 00/19] arm64: invoke syscalls with pt_regs Mark Rutland
                   ` (11 preceding siblings ...)
  2018-06-18 12:03 ` [PATCHv3 12/19] arm64: zero GPRs upon entry from EL0 Mark Rutland
@ 2018-06-18 12:03 ` Mark Rutland
  2018-06-19 15:45   ` Catalin Marinas
  2018-06-18 12:03 ` [PATCHv3 14/19] kernel: add kcompat_sys_{f,}statfs64() Mark Rutland
                   ` (6 subsequent siblings)
  19 siblings, 1 reply; 53+ messages in thread
From: Mark Rutland @ 2018-06-18 12:03 UTC (permalink / raw)
  To: linux-arm-kernel, catalin.marinas, will.deacon
  Cc: dave.martin, hch, james.morse, linux, linux-fsdevel,
	marc.zyngier, mark.rutland, viro

Using this helper allows us to avoid the in-kernel call to the
sys_personality() syscall. The ksys_ prefix denotes that this function
is meant as a drop-in replacement for the syscall. In particular, it
uses the same calling convention as sys_personality().

Since ksys_personality is trivial, it is implemented directly in
<linux/syscalls.h>, as we do for ksys_close() and friends.

This helper is necessary to enable conversion of arm64's syscall
handling to use pt_regs wrappers.

Signed-off-by: Mark Rutland <mark.rutland@arm.com>
Reviewed-by: Dominik Brodowski <linux@dominikbrodowski.net>
Cc: Al Viro <viro@zeniv.linux.org.uk>
Cc: Christoph Hellwig <hch@infradead.org>
Cc: Dave Martin <dave.martin@arm.com>
---
 include/linux/syscalls.h | 11 +++++++++++
 1 file changed, 11 insertions(+)

diff --git a/include/linux/syscalls.h b/include/linux/syscalls.h
index 73810808cdf2..14312d334345 100644
--- a/include/linux/syscalls.h
+++ b/include/linux/syscalls.h
@@ -80,6 +80,7 @@ union bpf_attr;
 #include <linux/unistd.h>
 #include <linux/quota.h>
 #include <linux/key.h>
+#include <linux/personality.h>
 #include <trace/syscall.h>
 
 #ifdef CONFIG_ARCH_HAS_SYSCALL_WRAPPER
@@ -1277,4 +1278,14 @@ static inline long ksys_truncate(const char __user *pathname, loff_t length)
 	return do_sys_truncate(pathname, length);
 }
 
+static inline unsigned int ksys_personality(unsigned int personality)
+{
+	unsigned int old = current->personality;
+
+	if (personality != 0xffffffff)
+		set_personality(personality);
+
+	return old;
+}
+
 #endif
-- 
2.11.0

^ permalink raw reply related	[flat|nested] 53+ messages in thread

* [PATCHv3 14/19] kernel: add kcompat_sys_{f,}statfs64()
  2018-06-18 12:02 [PATCHv3 00/19] arm64: invoke syscalls with pt_regs Mark Rutland
                   ` (12 preceding siblings ...)
  2018-06-18 12:03 ` [PATCHv3 13/19] kernel: add ksys_personality() Mark Rutland
@ 2018-06-18 12:03 ` Mark Rutland
  2018-06-18 12:03 ` [PATCHv3 15/19] arm64: remove in-kernel call to sys_personality() Mark Rutland
                   ` (5 subsequent siblings)
  19 siblings, 0 replies; 53+ messages in thread
From: Mark Rutland @ 2018-06-18 12:03 UTC (permalink / raw)
  To: linux-arm-kernel, catalin.marinas, will.deacon
  Cc: dave.martin, hch, james.morse, linux, linux-fsdevel,
	marc.zyngier, mark.rutland, viro

Using this helper allows us to avoid the in-kernel calls to the
compat_sys_{f,}statfs64() sycalls, as are necessary for parameter
mangling in arm64's compat handling.

Following the example of ksys_* functions, kcompat_sys_* functions are
intended to be a drop-in replacement for their compat_sys_*
counterparts, with the same calling convention.

This is necessary to enable conversion of arm64's syscall handling to
use pt_regs wrappers.

Signed-off-by: Mark Rutland <mark.rutland@arm.com>
Reviewed-by: Dominik Brodowski <linux@dominikbrodowski.net>
Cc: Al Viro <viro@zeniv.linux.org.uk>
Cc: linux-fsdevel@vger.kernel.org
---
 fs/statfs.c            | 14 ++++++++++++--
 include/linux/compat.h | 11 +++++++++++
 2 files changed, 23 insertions(+), 2 deletions(-)

diff --git a/fs/statfs.c b/fs/statfs.c
index 5b2a24f0f263..f0216629621d 100644
--- a/fs/statfs.c
+++ b/fs/statfs.c
@@ -335,7 +335,7 @@ static int put_compat_statfs64(struct compat_statfs64 __user *ubuf, struct kstat
 	return 0;
 }
 
-COMPAT_SYSCALL_DEFINE3(statfs64, const char __user *, pathname, compat_size_t, sz, struct compat_statfs64 __user *, buf)
+int kcompat_sys_statfs64(const char __user * pathname, compat_size_t sz, struct compat_statfs64 __user * buf)
 {
 	struct kstatfs tmp;
 	int error;
@@ -349,7 +349,12 @@ COMPAT_SYSCALL_DEFINE3(statfs64, const char __user *, pathname, compat_size_t, s
 	return error;
 }
 
-COMPAT_SYSCALL_DEFINE3(fstatfs64, unsigned int, fd, compat_size_t, sz, struct compat_statfs64 __user *, buf)
+COMPAT_SYSCALL_DEFINE3(statfs64, const char __user *, pathname, compat_size_t, sz, struct compat_statfs64 __user *, buf)
+{
+	return kcompat_sys_statfs64(pathname, sz, buf);
+}
+
+int kcompat_sys_fstatfs64(unsigned int fd, compat_size_t sz, struct compat_statfs64 __user * buf)
 {
 	struct kstatfs tmp;
 	int error;
@@ -363,6 +368,11 @@ COMPAT_SYSCALL_DEFINE3(fstatfs64, unsigned int, fd, compat_size_t, sz, struct co
 	return error;
 }
 
+COMPAT_SYSCALL_DEFINE3(fstatfs64, unsigned int, fd, compat_size_t, sz, struct compat_statfs64 __user *, buf)
+{
+	return kcompat_sys_fstatfs64(fd, sz, buf);
+}
+
 /*
  * This is a copy of sys_ustat, just dealing with a structure layout.
  * Given how simple this syscall is that apporach is more maintainable
diff --git a/include/linux/compat.h b/include/linux/compat.h
index b1a5562b3215..a9ead4a9d7fc 100644
--- a/include/linux/compat.h
+++ b/include/linux/compat.h
@@ -1022,6 +1022,17 @@ static inline struct compat_timeval ns_to_compat_timeval(s64 nsec)
 	return ctv;
 }
 
+/*
+ * Kernel code should not call compat syscalls (i.e., compat_sys_xyzyyz())
+ * directly.  Instead, use one of the functions which work equivalently, such
+ * as the kcompat_sys_xyzyyz() functions prototyped below.
+ */
+
+int kcompat_sys_statfs64(const char __user * pathname, compat_size_t sz,
+		     struct compat_statfs64 __user * buf);
+int kcompat_sys_fstatfs64(unsigned int fd, compat_size_t sz,
+			  struct compat_statfs64 __user * buf);
+
 #else /* !CONFIG_COMPAT */
 
 #define is_compat_task() (0)
-- 
2.11.0

^ permalink raw reply related	[flat|nested] 53+ messages in thread

* [PATCHv3 15/19] arm64: remove in-kernel call to sys_personality()
  2018-06-18 12:02 [PATCHv3 00/19] arm64: invoke syscalls with pt_regs Mark Rutland
                   ` (13 preceding siblings ...)
  2018-06-18 12:03 ` [PATCHv3 14/19] kernel: add kcompat_sys_{f,}statfs64() Mark Rutland
@ 2018-06-18 12:03 ` Mark Rutland
  2018-06-19 15:46   ` Catalin Marinas
  2018-06-18 12:03 ` [PATCHv3 16/19] arm64: use {COMPAT,}SYSCALL_DEFINE0 for sigreturn Mark Rutland
                   ` (4 subsequent siblings)
  19 siblings, 1 reply; 53+ messages in thread
From: Mark Rutland @ 2018-06-18 12:03 UTC (permalink / raw)
  To: linux-arm-kernel, catalin.marinas, will.deacon
  Cc: dave.martin, hch, james.morse, linux, linux-fsdevel,
	marc.zyngier, mark.rutland, viro

With pt_regs syscall wrappers, the calling convention for
sys_personality() will change. Use ksys_personality(), which is
functionally equivalent.

Signed-off-by: Mark Rutland <mark.rutland@arm.com>
Cc: Catalin Marinas <catalin.marinas@arm.com>
Cc: Will Deacon <will.deacon@arm.com>
---
 arch/arm64/kernel/sys.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/arch/arm64/kernel/sys.c b/arch/arm64/kernel/sys.c
index 31045f3fed92..a82c3f7a9a90 100644
--- a/arch/arm64/kernel/sys.c
+++ b/arch/arm64/kernel/sys.c
@@ -42,7 +42,7 @@ SYSCALL_DEFINE1(arm64_personality, unsigned int, personality)
 	if (personality(personality) == PER_LINUX32 &&
 		!system_supports_32bit_el0())
 		return -EINVAL;
-	return sys_personality(personality);
+	return ksys_personality(personality);
 }
 
 /*
-- 
2.11.0

^ permalink raw reply related	[flat|nested] 53+ messages in thread

* [PATCHv3 16/19] arm64: use {COMPAT,}SYSCALL_DEFINE0 for sigreturn
  2018-06-18 12:02 [PATCHv3 00/19] arm64: invoke syscalls with pt_regs Mark Rutland
                   ` (14 preceding siblings ...)
  2018-06-18 12:03 ` [PATCHv3 15/19] arm64: remove in-kernel call to sys_personality() Mark Rutland
@ 2018-06-18 12:03 ` Mark Rutland
  2018-06-19 15:48   ` Catalin Marinas
  2018-06-18 12:03 ` [PATCHv3 17/19] arm64: use SYSCALL_DEFINE6() for mmap Mark Rutland
                   ` (3 subsequent siblings)
  19 siblings, 1 reply; 53+ messages in thread
From: Mark Rutland @ 2018-06-18 12:03 UTC (permalink / raw)
  To: linux-arm-kernel, catalin.marinas, will.deacon
  Cc: dave.martin, hch, james.morse, linux, linux-fsdevel,
	marc.zyngier, mark.rutland, viro

We don't currently annotate our various sigreturn functions as syscalls,
as we need to do to use pt_regs syscall wrappers.

Let's mark them as real syscalls.

For compat_sys_sigreturn and compat_sys_rt_sigreturn, this changes the
return type from int to long, matching the prototypes in sys32.c.

Signed-off-by: Mark Rutland <mark.rutland@arm.com>
Reviewed-by: Dominik Brodowski <linux@dominikbrodowski.net>
Cc: Catalin Marinas <catalin.marinas@arm.com>
Cc: Will Deacon <will.deacon@arm.com>
---
 arch/arm64/kernel/signal.c   | 2 +-
 arch/arm64/kernel/signal32.c | 4 ++--
 2 files changed, 3 insertions(+), 3 deletions(-)

diff --git a/arch/arm64/kernel/signal.c b/arch/arm64/kernel/signal.c
index f03e664f773f..f8b0ba50e55e 100644
--- a/arch/arm64/kernel/signal.c
+++ b/arch/arm64/kernel/signal.c
@@ -539,7 +539,7 @@ static int restore_sigframe(struct pt_regs *regs,
 	return err;
 }
 
-asmlinkage long sys_rt_sigreturn(void)
+SYSCALL_DEFINE0(rt_sigreturn)
 {
 	struct pt_regs *regs = current_pt_regs();
 	struct rt_sigframe __user *frame;
diff --git a/arch/arm64/kernel/signal32.c b/arch/arm64/kernel/signal32.c
index cb10588a7cb2..1948566dcccf 100644
--- a/arch/arm64/kernel/signal32.c
+++ b/arch/arm64/kernel/signal32.c
@@ -282,7 +282,7 @@ static int compat_restore_sigframe(struct pt_regs *regs,
 	return err;
 }
 
-asmlinkage int compat_sys_sigreturn(void)
+COMPAT_SYSCALL_DEFINE0(sigreturn)
 {
 	struct pt_regs *regs = current_pt_regs();
 	struct compat_sigframe __user *frame;
@@ -313,7 +313,7 @@ asmlinkage int compat_sys_sigreturn(void)
 	return 0;
 }
 
-asmlinkage int compat_sys_rt_sigreturn(void)
+COMPAT_SYSCALL_DEFINE0(rt_sigreturn)
 {
 	struct pt_regs *regs = current_pt_regs();
 	struct compat_rt_sigframe __user *frame;
-- 
2.11.0

^ permalink raw reply related	[flat|nested] 53+ messages in thread

* [PATCHv3 17/19] arm64: use SYSCALL_DEFINE6() for mmap
  2018-06-18 12:02 [PATCHv3 00/19] arm64: invoke syscalls with pt_regs Mark Rutland
                   ` (15 preceding siblings ...)
  2018-06-18 12:03 ` [PATCHv3 16/19] arm64: use {COMPAT,}SYSCALL_DEFINE0 for sigreturn Mark Rutland
@ 2018-06-18 12:03 ` Mark Rutland
  2018-06-19 15:50   ` Catalin Marinas
  2018-06-18 12:03 ` [PATCHv3 18/19] arm64: convert compat wrappers to C Mark Rutland
                   ` (2 subsequent siblings)
  19 siblings, 1 reply; 53+ messages in thread
From: Mark Rutland @ 2018-06-18 12:03 UTC (permalink / raw)
  To: linux-arm-kernel, catalin.marinas, will.deacon
  Cc: dave.martin, hch, james.morse, linux, linux-fsdevel,
	marc.zyngier, mark.rutland, viro

We don't currently annotate our mmap implementation as a syscall, as we
need to do to use pt_regs syscall wrappers.

Let's mark it as a real syscall.

There should be no functional change as a result of this patch.

Signed-off-by: Mark Rutland <mark.rutland@arm.com>
Reviewed-by: Dominik Brodowski <linux@dominikbrodowski.net>
Cc: Catalin Marinas <catalin.marinas@arm.com>
Cc: Will Deacon <will.deacon@arm.com>
---
 arch/arm64/kernel/sys.c | 6 +++---
 1 file changed, 3 insertions(+), 3 deletions(-)

diff --git a/arch/arm64/kernel/sys.c b/arch/arm64/kernel/sys.c
index a82c3f7a9a90..2ad1497a184e 100644
--- a/arch/arm64/kernel/sys.c
+++ b/arch/arm64/kernel/sys.c
@@ -27,9 +27,9 @@
 #include <linux/syscalls.h>
 #include <asm/cpufeature.h>
 
-asmlinkage long sys_mmap(unsigned long addr, unsigned long len,
-			 unsigned long prot, unsigned long flags,
-			 unsigned long fd, off_t off)
+SYSCALL_DEFINE6(mmap, unsigned long, addr, unsigned long, len,
+		unsigned long, prot, unsigned long, flags,
+		unsigned long, fd, off_t, off)
 {
 	if (offset_in_page(off) != 0)
 		return -EINVAL;
-- 
2.11.0

^ permalink raw reply related	[flat|nested] 53+ messages in thread

* [PATCHv3 18/19] arm64: convert compat wrappers to C
  2018-06-18 12:02 [PATCHv3 00/19] arm64: invoke syscalls with pt_regs Mark Rutland
                   ` (16 preceding siblings ...)
  2018-06-18 12:03 ` [PATCHv3 17/19] arm64: use SYSCALL_DEFINE6() for mmap Mark Rutland
@ 2018-06-18 12:03 ` Mark Rutland
  2018-06-19 15:51   ` Catalin Marinas
  2018-06-18 12:03 ` [PATCHv3 19/19] arm64: implement syscall wrappers Mark Rutland
  2018-06-19 15:38 ` [PATCHv3 00/19] arm64: invoke syscalls with pt_regs Mark Rutland
  19 siblings, 1 reply; 53+ messages in thread
From: Mark Rutland @ 2018-06-18 12:03 UTC (permalink / raw)
  To: linux-arm-kernel, catalin.marinas, will.deacon
  Cc: dave.martin, hch, james.morse, linux, linux-fsdevel,
	marc.zyngier, mark.rutland, viro

In preparation for converting to pt_regs syscall wrappers, convert our
existing compat wrappers to C. This will allow the pt_regs wrappers to
be automatically generated, and will allow for the compat register
manipulation to be folded in with the pt_regs accesses.

To avoid confusion with the upcoming pt_regs wrappers and existing
compat wrappers provided by core code, the C wrappers are renamed to
compat_sys_aarch32_<syscall>.

With the assembly wrappers gone, we can get rid of entry32.S and the
associated boilerplate.

Note that these must call the ksys_* syscall entry points, as the usual
sys_* entry points will be modified to take a single pt_regs pointer
argument.

Signed-off-by: Mark Rutland <mark.rutland@arm.com>
Cc: Catalin Marinas <catalin.marinas@arm.com>
Cc: Will Deacon <will.deacon@arm.com>
---
 arch/arm64/include/asm/unistd32.h |  22 ++++----
 arch/arm64/kernel/Makefile        |   2 +-
 arch/arm64/kernel/entry32.S       | 111 -------------------------------------
 arch/arm64/kernel/sys32.c         | 114 ++++++++++++++++++++++++++++++++++----
 4 files changed, 115 insertions(+), 134 deletions(-)
 delete mode 100644 arch/arm64/kernel/entry32.S

diff --git a/arch/arm64/include/asm/unistd32.h b/arch/arm64/include/asm/unistd32.h
index ab95554b1734..0e3dd3265993 100644
--- a/arch/arm64/include/asm/unistd32.h
+++ b/arch/arm64/include/asm/unistd32.h
@@ -382,9 +382,9 @@ __SYSCALL(__NR_rt_sigqueueinfo, compat_sys_rt_sigqueueinfo)
 #define __NR_rt_sigsuspend 179
 __SYSCALL(__NR_rt_sigsuspend, compat_sys_rt_sigsuspend)
 #define __NR_pread64 180
-__SYSCALL(__NR_pread64, compat_sys_pread64_wrapper)
+__SYSCALL(__NR_pread64, compat_sys_aarch32_pread64)
 #define __NR_pwrite64 181
-__SYSCALL(__NR_pwrite64, compat_sys_pwrite64_wrapper)
+__SYSCALL(__NR_pwrite64, compat_sys_aarch32_pwrite64)
 #define __NR_chown 182
 __SYSCALL(__NR_chown, sys_chown16)
 #define __NR_getcwd 183
@@ -406,11 +406,11 @@ __SYSCALL(__NR_vfork, sys_vfork)
 #define __NR_ugetrlimit 191	/* SuS compliant getrlimit */
 __SYSCALL(__NR_ugetrlimit, compat_sys_getrlimit)		/* SuS compliant getrlimit */
 #define __NR_mmap2 192
-__SYSCALL(__NR_mmap2, compat_sys_mmap2_wrapper)
+__SYSCALL(__NR_mmap2, compat_sys_aarch32_mmap2)
 #define __NR_truncate64 193
-__SYSCALL(__NR_truncate64, compat_sys_truncate64_wrapper)
+__SYSCALL(__NR_truncate64, compat_sys_aarch32_truncate64)
 #define __NR_ftruncate64 194
-__SYSCALL(__NR_ftruncate64, compat_sys_ftruncate64_wrapper)
+__SYSCALL(__NR_ftruncate64, compat_sys_aarch32_ftruncate64)
 #define __NR_stat64 195
 __SYSCALL(__NR_stat64, sys_stat64)
 #define __NR_lstat64 196
@@ -472,7 +472,7 @@ __SYSCALL(223, sys_ni_syscall)
 #define __NR_gettid 224
 __SYSCALL(__NR_gettid, sys_gettid)
 #define __NR_readahead 225
-__SYSCALL(__NR_readahead, compat_sys_readahead_wrapper)
+__SYSCALL(__NR_readahead, compat_sys_aarch32_readahead)
 #define __NR_setxattr 226
 __SYSCALL(__NR_setxattr, sys_setxattr)
 #define __NR_lsetxattr 227
@@ -554,15 +554,15 @@ __SYSCALL(__NR_clock_getres, compat_sys_clock_getres)
 #define __NR_clock_nanosleep 265
 __SYSCALL(__NR_clock_nanosleep, compat_sys_clock_nanosleep)
 #define __NR_statfs64 266
-__SYSCALL(__NR_statfs64, compat_sys_statfs64_wrapper)
+__SYSCALL(__NR_statfs64, compat_sys_aarch32_statfs64)
 #define __NR_fstatfs64 267
-__SYSCALL(__NR_fstatfs64, compat_sys_fstatfs64_wrapper)
+__SYSCALL(__NR_fstatfs64, compat_sys_aarch32_fstatfs64)
 #define __NR_tgkill 268
 __SYSCALL(__NR_tgkill, sys_tgkill)
 #define __NR_utimes 269
 __SYSCALL(__NR_utimes, compat_sys_utimes)
 #define __NR_arm_fadvise64_64 270
-__SYSCALL(__NR_arm_fadvise64_64, compat_sys_fadvise64_64_wrapper)
+__SYSCALL(__NR_arm_fadvise64_64, compat_sys_aarch32_fadvise64_64)
 #define __NR_pciconfig_iobase 271
 __SYSCALL(__NR_pciconfig_iobase, sys_pciconfig_iobase)
 #define __NR_pciconfig_read 272
@@ -704,7 +704,7 @@ __SYSCALL(__NR_get_robust_list, compat_sys_get_robust_list)
 #define __NR_splice 340
 __SYSCALL(__NR_splice, sys_splice)
 #define __NR_sync_file_range2 341
-__SYSCALL(__NR_sync_file_range2, compat_sys_sync_file_range2_wrapper)
+__SYSCALL(__NR_sync_file_range2, compat_sys_aarch32_sync_file_range2)
 #define __NR_tee 342
 __SYSCALL(__NR_tee, sys_tee)
 #define __NR_vmsplice 343
@@ -726,7 +726,7 @@ __SYSCALL(__NR_timerfd_create, sys_timerfd_create)
 #define __NR_eventfd 351
 __SYSCALL(__NR_eventfd, sys_eventfd)
 #define __NR_fallocate 352
-__SYSCALL(__NR_fallocate, compat_sys_fallocate_wrapper)
+__SYSCALL(__NR_fallocate, compat_sys_aarch32_fallocate)
 #define __NR_timerfd_settime 353
 __SYSCALL(__NR_timerfd_settime, compat_sys_timerfd_settime)
 #define __NR_timerfd_gettime 354
diff --git a/arch/arm64/kernel/Makefile b/arch/arm64/kernel/Makefile
index 4e24d2244bd1..95ac7374d723 100644
--- a/arch/arm64/kernel/Makefile
+++ b/arch/arm64/kernel/Makefile
@@ -28,7 +28,7 @@ $(obj)/%.stub.o: $(obj)/%.o FORCE
 	$(call if_changed,objcopy)
 
 arm64-obj-$(CONFIG_COMPAT)		+= sys32.o kuser32.o signal32.o 	\
-					   sys_compat.o entry32.o
+					   sys_compat.o
 arm64-obj-$(CONFIG_FUNCTION_TRACER)	+= ftrace.o entry-ftrace.o
 arm64-obj-$(CONFIG_MODULES)		+= arm64ksyms.o module.o
 arm64-obj-$(CONFIG_ARM64_MODULE_PLTS)	+= module-plts.o
diff --git a/arch/arm64/kernel/entry32.S b/arch/arm64/kernel/entry32.S
deleted file mode 100644
index f9461696dde4..000000000000
--- a/arch/arm64/kernel/entry32.S
+++ /dev/null
@@ -1,111 +0,0 @@
-/*
- * Compat system call wrappers
- *
- * Copyright (C) 2012 ARM Ltd.
- * Authors: Will Deacon <will.deacon@arm.com>
- *	    Catalin Marinas <catalin.marinas@arm.com>
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 as
- * published by the Free Software Foundation.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program.  If not, see <http://www.gnu.org/licenses/>.
- */
-
-#include <linux/linkage.h>
-#include <linux/const.h>
-
-#include <asm/assembler.h>
-#include <asm/asm-offsets.h>
-#include <asm/errno.h>
-#include <asm/page.h>
-
-/*
- * System call wrappers for the AArch32 compatibility layer.
- */
-
-ENTRY(compat_sys_statfs64_wrapper)
-	mov	w3, #84
-	cmp	w1, #88
-	csel	w1, w3, w1, eq
-	b	compat_sys_statfs64
-ENDPROC(compat_sys_statfs64_wrapper)
-
-ENTRY(compat_sys_fstatfs64_wrapper)
-	mov	w3, #84
-	cmp	w1, #88
-	csel	w1, w3, w1, eq
-	b	compat_sys_fstatfs64
-ENDPROC(compat_sys_fstatfs64_wrapper)
-
-/*
- * Note: off_4k (w5) is always in units of 4K. If we can't do the
- * requested offset because it is not page-aligned, we return -EINVAL.
- */
-ENTRY(compat_sys_mmap2_wrapper)
-#if PAGE_SHIFT > 12
-	tst	w5, #~PAGE_MASK >> 12
-	b.ne	1f
-	lsr	w5, w5, #PAGE_SHIFT - 12
-#endif
-	b	sys_mmap_pgoff
-1:	mov	x0, #-EINVAL
-	ret
-ENDPROC(compat_sys_mmap2_wrapper)
-
-/*
- * Wrappers for AArch32 syscalls that either take 64-bit parameters
- * in registers or that take 32-bit parameters which require sign
- * extension.
- */
-ENTRY(compat_sys_pread64_wrapper)
-	regs_to_64	x3, x4, x5
-	b	sys_pread64
-ENDPROC(compat_sys_pread64_wrapper)
-
-ENTRY(compat_sys_pwrite64_wrapper)
-	regs_to_64	x3, x4, x5
-	b	sys_pwrite64
-ENDPROC(compat_sys_pwrite64_wrapper)
-
-ENTRY(compat_sys_truncate64_wrapper)
-	regs_to_64	x1, x2, x3
-	b	sys_truncate
-ENDPROC(compat_sys_truncate64_wrapper)
-
-ENTRY(compat_sys_ftruncate64_wrapper)
-	regs_to_64	x1, x2, x3
-	b	sys_ftruncate
-ENDPROC(compat_sys_ftruncate64_wrapper)
-
-ENTRY(compat_sys_readahead_wrapper)
-	regs_to_64	x1, x2, x3
-	mov	w2, w4
-	b	sys_readahead
-ENDPROC(compat_sys_readahead_wrapper)
-
-ENTRY(compat_sys_fadvise64_64_wrapper)
-	mov	w6, w1
-	regs_to_64	x1, x2, x3
-	regs_to_64	x2, x4, x5
-	mov	w3, w6
-	b	sys_fadvise64_64
-ENDPROC(compat_sys_fadvise64_64_wrapper)
-
-ENTRY(compat_sys_sync_file_range2_wrapper)
-	regs_to_64	x2, x2, x3
-	regs_to_64	x3, x4, x5
-	b	sys_sync_file_range2
-ENDPROC(compat_sys_sync_file_range2_wrapper)
-
-ENTRY(compat_sys_fallocate_wrapper)
-	regs_to_64	x2, x2, x3
-	regs_to_64	x3, x4, x5
-	b	sys_fallocate
-ENDPROC(compat_sys_fallocate_wrapper)
diff --git a/arch/arm64/kernel/sys32.c b/arch/arm64/kernel/sys32.c
index 1ef103c95410..793bd0952ee0 100644
--- a/arch/arm64/kernel/sys32.c
+++ b/arch/arm64/kernel/sys32.c
@@ -22,22 +22,114 @@
  */
 #define __COMPAT_SYSCALL_NR
 
+#include <linux/compat.h>
 #include <linux/compiler.h>
 #include <linux/syscalls.h>
 
 asmlinkage long compat_sys_sigreturn(void);
 asmlinkage long compat_sys_rt_sigreturn(void);
-asmlinkage long compat_sys_statfs64_wrapper(void);
-asmlinkage long compat_sys_fstatfs64_wrapper(void);
-asmlinkage long compat_sys_pread64_wrapper(void);
-asmlinkage long compat_sys_pwrite64_wrapper(void);
-asmlinkage long compat_sys_truncate64_wrapper(void);
-asmlinkage long compat_sys_ftruncate64_wrapper(void);
-asmlinkage long compat_sys_readahead_wrapper(void);
-asmlinkage long compat_sys_fadvise64_64_wrapper(void);
-asmlinkage long compat_sys_sync_file_range2_wrapper(void);
-asmlinkage long compat_sys_fallocate_wrapper(void);
-asmlinkage long compat_sys_mmap2_wrapper(void);
+
+COMPAT_SYSCALL_DEFINE3(aarch32_statfs64, const char __user *, pathname,
+		       compat_size_t, sz, struct compat_statfs64 __user *, buf)
+{
+	/*
+	 * 32-bit ARM applies an OABI compatibility fixup to statfs64 and
+	 * fstatfs64 regardless of whether OABI is in use, and therefore
+	 * arbitrary binaries may rely upon it, so we must do the same.
+	 * For more details, see commit:
+	 *
+	 * 713c481519f19df9 ("[ARM] 3108/2: old ABI compat: statfs64 and
+	 * fstatfs64")
+	 */
+	if (sz == 88)
+		sz = 84;
+
+	return kcompat_sys_statfs64(pathname, sz, buf);
+}
+
+COMPAT_SYSCALL_DEFINE3(aarch32_fstatfs64, unsigned int, fd, compat_size_t, sz,
+		       struct compat_statfs64 __user *, buf)
+{
+	/* see aarch32_statfs64 */
+	if (sz == 88)
+		sz = 84;
+
+	return kcompat_sys_fstatfs64(fd, sz, buf);
+}
+
+/*
+ * Note: off_4k is always in units of 4K. If we can't do the
+ * requested offset because it is not page-aligned, we return -EINVAL.
+ */
+COMPAT_SYSCALL_DEFINE6(aarch32_mmap2, unsigned long, addr, unsigned long, len,
+		       unsigned long, prot, unsigned long, flags,
+		       unsigned long, fd, unsigned long, off_4k)
+{
+	if (off_4k & (~PAGE_MASK >> 12))
+		return -EINVAL;
+
+	off_4k >>= (PAGE_SHIFT - 12);
+
+	return ksys_mmap_pgoff(addr, len, prot, flags, fd, off_4k);
+}
+
+#ifdef CONFIG_CPU_BIG_ENDIAN
+#define arg_u32p(name)	u32, name##_hi, u32, name##_lo
+#else
+#define arg_u32p(name)	u32, name##_lo, u32, name##_hi
+#endif
+
+#define arg_u64(name)	(((u64)name##_hi << 32) | name##_lo)
+
+COMPAT_SYSCALL_DEFINE6(aarch32_pread64, unsigned int, fd, char __user *, buf,
+		       size_t, count, u32, __pad, arg_u32p(pos))
+{
+	return ksys_pread64(fd, buf, count, arg_u64(pos));
+}
+
+COMPAT_SYSCALL_DEFINE6(aarch32_pwrite64, unsigned int, fd,
+		       const char __user *, buf, size_t, count, u32, __pad,
+		       arg_u32p(pos))
+{
+	return ksys_pwrite64(fd, buf, count, arg_u64(pos));
+}
+
+COMPAT_SYSCALL_DEFINE4(aarch32_truncate64, const char __user *, pathname,
+		       u32, __pad, arg_u32p(length))
+{
+	return ksys_truncate(pathname, arg_u64(length));
+}
+
+COMPAT_SYSCALL_DEFINE4(aarch32_ftruncate64, unsigned int, fd, u32, __pad,
+		       arg_u32p(length))
+{
+	return ksys_ftruncate(fd, arg_u64(length));
+}
+
+COMPAT_SYSCALL_DEFINE5(aarch32_readahead, int, fd, u32, __pad,
+		       arg_u32p(offset), size_t, count)
+{
+	return ksys_readahead(fd, arg_u64(offset), count);
+}
+
+COMPAT_SYSCALL_DEFINE6(aarch32_fadvise64_64, int, fd, int, advice,
+		       arg_u32p(offset), arg_u32p(len))
+{
+	return ksys_fadvise64_64(fd, arg_u64(offset), arg_u64(len), advice);
+}
+
+COMPAT_SYSCALL_DEFINE6(aarch32_sync_file_range2, int, fd, unsigned int, flags,
+		       arg_u32p(offset), arg_u32p(nbytes))
+{
+	return ksys_sync_file_range(fd, arg_u64(offset), arg_u64(nbytes),
+				    flags);
+}
+
+COMPAT_SYSCALL_DEFINE6(aarch32_fallocate, int, fd, int, mode,
+		       arg_u32p(offset), arg_u32p(len))
+{
+	return ksys_fallocate(fd, mode, arg_u64(offset), arg_u64(len));
+}
 
 #undef __SYSCALL
 #define __SYSCALL(nr, sym)	[nr] = sym,
-- 
2.11.0

^ permalink raw reply related	[flat|nested] 53+ messages in thread

* [PATCHv3 19/19] arm64: implement syscall wrappers
  2018-06-18 12:02 [PATCHv3 00/19] arm64: invoke syscalls with pt_regs Mark Rutland
                   ` (17 preceding siblings ...)
  2018-06-18 12:03 ` [PATCHv3 18/19] arm64: convert compat wrappers to C Mark Rutland
@ 2018-06-18 12:03 ` Mark Rutland
  2018-06-19 16:13   ` Catalin Marinas
  2018-06-19 15:38 ` [PATCHv3 00/19] arm64: invoke syscalls with pt_regs Mark Rutland
  19 siblings, 1 reply; 53+ messages in thread
From: Mark Rutland @ 2018-06-18 12:03 UTC (permalink / raw)
  To: linux-arm-kernel, catalin.marinas, will.deacon
  Cc: dave.martin, hch, james.morse, linux, linux-fsdevel,
	marc.zyngier, mark.rutland, viro

To minimize the risk of userspace-controlled values being used under
speculation, this patch adds pt_regs based syscall wrappers for arm64,
which pass the minimum set of required userspace values to syscall
implementations. For each syscall, a wrapper which takes a pt_regs
argument is automatically generated, and this extracts the arguments
before calling the "real" syscall implementation.

Each syscall has three functions generated:

* __do_<compat_>sys_<name> is the "real" syscall implementation, with
  the expected prototype.

* __se_<compat_>sys_<name> is the sign-extension/narrowing wrapper,
  inherited from common code. This takes a series of long parameters,
  casting each to the requisite types required by the "real" syscall
  implementation in __do_<compat_>sys_<name>.

  This wrapper *may* not be necessary on arm64 given the AAPCS rules on
  unused register bits, but it seemed safer to keep the wrapper for now.

* __arm64_<compat_>_sys_<name> takes a struct pt_regs pointer, and
  extracts *only* the relevant register values, passing these on to the
  __se_<compat_>sys_<name> wrapper.

The syscall invocation code is updated to handle the calling convention
required by __arm64_<compat_>_sys_<name>, and passes a single struct
pt_regs pointer.

The compiler can fold the syscall implementation and its wrappers, such
that the overhead of this approach is minimized.

Note that we play games with sys_ni_syscall(). It can't be defined with
SYSCALL_DEFINE0() because we must avoid the possibility of error
injection. Additionally, there are a couple of locations where we need
to call it from C code, and we don't (currently) have a
ksys_ni_syscall().  While it has no wrapper, passing in a redundant
pt_regs pointer is benign per the AAPCS.

When ARCH_HAS_SYSCALL_WRAPPER is selected, no prototype is defines for
sys_ni_syscall(). Since we need to treat it differently for in-kernel
calls and the syscall tables, the prototype is defined as-required.

The wrappers are largely the same as their x86 counterparts, but
simplified as we don't have a variety of compat calling conventions that
require separate stubs. Unlike x86, we have some zero-argument compat
syscalls, and must define COMPAT_SYSCALL_DEFINE0() to ensure that these
are also given an __arm64_compat_sys_ prefix.

Signed-off-by: Mark Rutland <mark.rutland@arm.com>
Reviewed-by: Dominik Brodowski <linux@dominikbrodowski.net>
Cc: Catalin Marinas <catalin.marinas@arm.com>
Cc: Will Deacon <will.deacon@arm.com>
---
 arch/arm64/Kconfig                       |  1 +
 arch/arm64/include/asm/syscall_wrapper.h | 80 ++++++++++++++++++++++++++++++++
 arch/arm64/kernel/sys.c                  | 10 +++-
 arch/arm64/kernel/sys32.c                |  9 +++-
 arch/arm64/kernel/syscall.c              |  8 +---
 arch/arm64/kernel/traps.c                |  2 +
 6 files changed, 101 insertions(+), 9 deletions(-)
 create mode 100644 arch/arm64/include/asm/syscall_wrapper.h

diff --git a/arch/arm64/Kconfig b/arch/arm64/Kconfig
index 42c090cf0292..2089aa3f27bc 100644
--- a/arch/arm64/Kconfig
+++ b/arch/arm64/Kconfig
@@ -24,6 +24,7 @@ config ARM64
 	select ARCH_HAS_SG_CHAIN
 	select ARCH_HAS_STRICT_KERNEL_RWX
 	select ARCH_HAS_STRICT_MODULE_RWX
+	select ARCH_HAS_SYSCALL_WRAPPER
 	select ARCH_HAS_TICK_BROADCAST if GENERIC_CLOCKEVENTS_BROADCAST
 	select ARCH_HAVE_NMI_SAFE_CMPXCHG
 	select ARCH_INLINE_READ_LOCK if !PREEMPT
diff --git a/arch/arm64/include/asm/syscall_wrapper.h b/arch/arm64/include/asm/syscall_wrapper.h
new file mode 100644
index 000000000000..a4477e515b79
--- /dev/null
+++ b/arch/arm64/include/asm/syscall_wrapper.h
@@ -0,0 +1,80 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+/*
+ * syscall_wrapper.h - arm64 specific wrappers to syscall definitions
+ *
+ * Based on arch/x86/include/asm_syscall_wrapper.h
+ */
+
+#ifndef __ASM_SYSCALL_WRAPPER_H
+#define __ASM_SYSCALL_WRAPPER_H
+
+#define SC_ARM64_REGS_TO_ARGS(x, ...)				\
+	__MAP(x,__SC_ARGS					\
+	      ,,regs->regs[0],,regs->regs[1],,regs->regs[2]	\
+	      ,,regs->regs[3],,regs->regs[4],,regs->regs[5])
+
+#ifdef CONFIG_COMPAT
+
+#define COMPAT_SYSCALL_DEFINEx(x, name, ...)						\
+	asmlinkage long __arm64_compat_sys##name(const struct pt_regs *regs);		\
+	ALLOW_ERROR_INJECTION(__arm64_compat_sys##name, ERRNO);				\
+	static long __se_compat_sys##name(__MAP(x,__SC_LONG,__VA_ARGS__));		\
+	static inline long __do_compat_sys##name(__MAP(x,__SC_DECL,__VA_ARGS__));	\
+	asmlinkage long __arm64_compat_sys##name(const struct pt_regs *regs)		\
+	{										\
+		return __se_compat_sys##name(SC_ARM64_REGS_TO_ARGS(x,__VA_ARGS__));	\
+	}										\
+	static long __se_compat_sys##name(__MAP(x,__SC_LONG,__VA_ARGS__))		\
+	{										\
+		return __do_compat_sys##name(__MAP(x,__SC_DELOUSE,__VA_ARGS__));	\
+	}										\
+	static inline long __do_compat_sys##name(__MAP(x,__SC_DECL,__VA_ARGS__))
+
+#define COMPAT_SYSCALL_DEFINE0(sname)					\
+	asmlinkage long __arm64_compat_sys_##sname(void);		\
+	ALLOW_ERROR_INJECTION(__arm64_compat_sys_##sname, ERRNO);	\
+	asmlinkage long __arm64_compat_sys_##sname(void)
+
+#define COND_SYSCALL_COMPAT(name) \
+	cond_syscall(__arm64_compat_sys_##name);
+
+#define COMPAT_SYS_NI(name) \
+	SYSCALL_ALIAS(__arm64_compat_sys_##name, sys_ni_posix_timers);
+
+#endif /* CONFIG_COMPAT */
+
+#define __SYSCALL_DEFINEx(x, name, ...)						\
+	asmlinkage long __arm64_sys##name(const struct pt_regs *regs);		\
+	ALLOW_ERROR_INJECTION(__arm64_sys##name, ERRNO);			\
+	static long __se_sys##name(__MAP(x,__SC_LONG,__VA_ARGS__));		\
+	static inline long __do_sys##name(__MAP(x,__SC_DECL,__VA_ARGS__));	\
+	asmlinkage long __arm64_sys##name(const struct pt_regs *regs)		\
+	{									\
+		return __se_sys##name(SC_ARM64_REGS_TO_ARGS(x,__VA_ARGS__));	\
+	}									\
+	static long __se_sys##name(__MAP(x,__SC_LONG,__VA_ARGS__))		\
+	{									\
+		long ret = __do_sys##name(__MAP(x,__SC_CAST,__VA_ARGS__));	\
+		__MAP(x,__SC_TEST,__VA_ARGS__);					\
+		__PROTECT(x, ret,__MAP(x,__SC_ARGS,__VA_ARGS__));		\
+		return ret;							\
+	}									\
+	static inline long __do_sys##name(__MAP(x,__SC_DECL,__VA_ARGS__))
+
+#ifndef SYSCALL_DEFINE0
+#define SYSCALL_DEFINE0(sname)					\
+	SYSCALL_METADATA(_##sname, 0);				\
+	asmlinkage long __arm64_sys_##sname(void);		\
+	ALLOW_ERROR_INJECTION(__arm64_sys_##sname, ERRNO);	\
+	asmlinkage long __arm64_sys_##sname(void)
+#endif
+
+#ifndef COND_SYSCALL
+#define COND_SYSCALL(name) cond_syscall(__arm64_sys_##name)
+#endif
+
+#ifndef SYS_NI
+#define SYS_NI(name) SYSCALL_ALIAS(__arm64_sys_##name, sys_ni_posix_timers);
+#endif
+
+#endif /* __ASM_SYSCALL_WRAPPER_H */
diff --git a/arch/arm64/kernel/sys.c b/arch/arm64/kernel/sys.c
index 2ad1497a184e..ee93bf789f0a 100644
--- a/arch/arm64/kernel/sys.c
+++ b/arch/arm64/kernel/sys.c
@@ -48,11 +48,17 @@ SYSCALL_DEFINE1(arm64_personality, unsigned int, personality)
 /*
  * Wrappers to pass the pt_regs argument.
  */
-asmlinkage long sys_rt_sigreturn(void);
 #define sys_personality		sys_arm64_personality
 
+asmlinkage long sys_ni_syscall(const struct pt_regs *);
+#define __arm64_sys_ni_syscall	sys_ni_syscall
+
+#undef __SYSCALL
+#define __SYSCALL(nr, sym)	asmlinkage long __arm64_##sym(const struct pt_regs *);
+#include <asm/unistd.h>
+
 #undef __SYSCALL
-#define __SYSCALL(nr, sym)	[nr] = sym,
+#define __SYSCALL(nr, sym)	[nr] = __arm64_##sym,
 
 /*
  * The sys_call_table array must be 4K aligned to be accessible from
diff --git a/arch/arm64/kernel/sys32.c b/arch/arm64/kernel/sys32.c
index 793bd0952ee0..533c97c5c232 100644
--- a/arch/arm64/kernel/sys32.c
+++ b/arch/arm64/kernel/sys32.c
@@ -131,8 +131,15 @@ COMPAT_SYSCALL_DEFINE6(aarch32_fallocate, int, fd, int, mode,
 	return ksys_fallocate(fd, mode, arg_u64(offset), arg_u64(len));
 }
 
+asmlinkage long sys_ni_syscall(const struct pt_regs *);
+#define __arm64_sys_ni_syscall	sys_ni_syscall
+
+#undef __SYSCALL
+#define __SYSCALL(nr, sym)	asmlinkage long __arm64_##sym(const struct pt_regs *);
+#include <asm/unistd32.h>
+
 #undef __SYSCALL
-#define __SYSCALL(nr, sym)	[nr] = sym,
+#define __SYSCALL(nr, sym)	[nr] = __arm64_##sym,
 
 /*
  * The sys_call_table array must be 4K aligned to be accessible from
diff --git a/arch/arm64/kernel/syscall.c b/arch/arm64/kernel/syscall.c
index 6a31bb2a382b..e5985924f57e 100644
--- a/arch/arm64/kernel/syscall.c
+++ b/arch/arm64/kernel/syscall.c
@@ -12,15 +12,11 @@
 
 long do_ni_syscall(struct pt_regs *regs);
 
-typedef long (*syscall_fn_t)(unsigned long, unsigned long,
-			     unsigned long, unsigned long,
-			     unsigned long, unsigned long);
+typedef long (*syscall_fn_t)(struct pt_regs *regs);
 
 static void __invoke_syscall(struct pt_regs *regs, syscall_fn_t syscall_fn)
 {
-	regs->regs[0] = syscall_fn(regs->regs[0], regs->regs[1],
-				   regs->regs[2], regs->regs[3],
-				   regs->regs[4], regs->regs[5]);
+	regs->regs[0] = syscall_fn(regs);
 }
 
 static void invoke_syscall(struct pt_regs *regs, unsigned int scno,
diff --git a/arch/arm64/kernel/traps.c b/arch/arm64/kernel/traps.c
index c27292703bd1..d941942043e5 100644
--- a/arch/arm64/kernel/traps.c
+++ b/arch/arm64/kernel/traps.c
@@ -549,6 +549,8 @@ asmlinkage void __exception do_sysinstr(unsigned int esr, struct pt_regs *regs)
 
 long compat_arm_syscall(struct pt_regs *regs);
 
+long sys_ni_syscall(void);
+
 asmlinkage long do_ni_syscall(struct pt_regs *regs)
 {
 #ifdef CONFIG_COMPAT
-- 
2.11.0

^ permalink raw reply related	[flat|nested] 53+ messages in thread

* Re: [PATCHv3 01/19] arm64: consistently use unsigned long for thread flags
  2018-06-18 12:02 ` [PATCHv3 01/19] arm64: consistently use unsigned long for thread flags Mark Rutland
@ 2018-06-19 10:49   ` Catalin Marinas
  2018-06-19 11:19     ` Mark Rutland
  0 siblings, 1 reply; 53+ messages in thread
From: Catalin Marinas @ 2018-06-19 10:49 UTC (permalink / raw)
  To: Mark Rutland
  Cc: linux-arm-kernel, will.deacon, marc.zyngier, linux, hch,
	james.morse, viro, linux-fsdevel, dave.martin

On Mon, Jun 18, 2018 at 01:02:52PM +0100, Mark Rutland wrote:
> In do_notify_resume, we manipulate thread_flags as a 32-bit unsigned
> int, whereas thread_info::flags is a 64-bit unsigned long, and elsewhere
> (e.g. in the entry assembly) we manipulate the flags as a 64-bit
> quantity.
> 
> For consistency, and to avoid problems if we end up with more than 32
> flags, let's make do_notify_resume take the flags as a 64-bit unsigned
> long.

When we get to more than 32 flags, you may want to modify the _TIF_*
definitions as well to (UL(1) << TIF_*). In the meantime:

Acked-by: Catalin Marinas <catalin.marinas@arm.com>

^ permalink raw reply	[flat|nested] 53+ messages in thread

* Re: [PATCHv3 02/19] arm64: move SCTLR_EL{1, 2} assertions to <asm/sysreg.h>
  2018-06-18 12:02 ` [PATCHv3 02/19] arm64: move SCTLR_EL{1,2} assertions to <asm/sysreg.h> Mark Rutland
@ 2018-06-19 11:02   ` Catalin Marinas
  2018-06-19 11:48   ` [PATCHv3 02/19] arm64: move SCTLR_EL{1,2} " Mark Rutland
  1 sibling, 0 replies; 53+ messages in thread
From: Catalin Marinas @ 2018-06-19 11:02 UTC (permalink / raw)
  To: Mark Rutland
  Cc: linux-arm-kernel, will.deacon, marc.zyngier, linux, hch,
	james.morse, viro, linux-fsdevel, dave.martin

On Mon, Jun 18, 2018 at 01:02:53PM +0100, Mark Rutland wrote:
> Currently we assert that the SCTLR_EL{1,2}_{SET,CLEAR} bits are
> self-consistent with an assertion in config_sctlr_el1(). This is a bit
> unusual, since config_sctlr_el1() doesn't make use of these definitions,
> and is far away from the definitions themselves.
> 
> We can use the CPP #error directive to have equivalent assertions in
> <asm/sysreg.h>, next to the definitions of the set/clear bits, which is
> a bit clearer and simpler.
> 
> At the same time, lets fill in the upper 32 bits for both registers in
> their repsective RES0 definitions. This could be a little nicer with
> GENMASK_ULL(63, 32), but this currently lives in <linux/bitops.h>, which
> cannot safely be included from assembly, as <asm/sysreg.h> can.
> 
> Note the when the preprocessor evaluates an expression for an #if
> directive, all signed or unsigned values are treated as intmax_t or
> uintmax_t respectively. To avoid ambiguity, we define explicitly define
> the mask of all 64 bits.
> 
> Signed-off-by: Mark Rutland <mark.rutland@arm.com>
> Cc: Catalin Marinas <catalin.marinas@arm.com>
> Cc: Dave Martin <dave.martin@arm.com>
> Cc: James Morse <james.morse@arm.com>
> Cc: Will Deacon <will.deacon@arm.com>

Acked-by: Catalin Marinas <catalin.marinas@arm.com>

^ permalink raw reply	[flat|nested] 53+ messages in thread

* Re: [PATCHv3 01/19] arm64: consistently use unsigned long for thread flags
  2018-06-19 10:49   ` Catalin Marinas
@ 2018-06-19 11:19     ` Mark Rutland
  0 siblings, 0 replies; 53+ messages in thread
From: Mark Rutland @ 2018-06-19 11:19 UTC (permalink / raw)
  To: Catalin Marinas
  Cc: linux-arm-kernel, will.deacon, marc.zyngier, linux, hch,
	james.morse, viro, linux-fsdevel, dave.martin

On Tue, Jun 19, 2018 at 11:49:40AM +0100, Catalin Marinas wrote:
> On Mon, Jun 18, 2018 at 01:02:52PM +0100, Mark Rutland wrote:
> > In do_notify_resume, we manipulate thread_flags as a 32-bit unsigned
> > int, whereas thread_info::flags is a 64-bit unsigned long, and elsewhere
> > (e.g. in the entry assembly) we manipulate the flags as a 64-bit
> > quantity.
> > 
> > For consistency, and to avoid problems if we end up with more than 32
> > flags, let's make do_notify_resume take the flags as a 64-bit unsigned
> > long.
> 
> When we get to more than 32 flags, you may want to modify the _TIF_*
> definitions as well to (UL(1) << TIF_*).

Agreed. I can spin a patch or two for a that as a subsequent cleanup.

> In the meantime:
> 
> Acked-by: Catalin Marinas <catalin.marinas@arm.com>

Cheers!

Mark.

^ permalink raw reply	[flat|nested] 53+ messages in thread

* Re: [PATCHv3 03/19] arm64: introduce sysreg_clear_set()
  2018-06-18 12:02 ` [PATCHv3 03/19] arm64: introduce sysreg_clear_set() Mark Rutland
@ 2018-06-19 11:44   ` Catalin Marinas
  2018-06-19 11:47   ` Marc Zyngier
  1 sibling, 0 replies; 53+ messages in thread
From: Catalin Marinas @ 2018-06-19 11:44 UTC (permalink / raw)
  To: Mark Rutland
  Cc: linux-arm-kernel, will.deacon, marc.zyngier, linux, hch,
	james.morse, viro, linux-fsdevel, dave.martin

On Mon, Jun 18, 2018 at 01:02:54PM +0100, Mark Rutland wrote:
> Currently we have a couple of helpers to manipulate bits in particular
> sysregs:
> 
>  * config_sctlr_el1(u32 clear, u32 set)
> 
>  * change_cpacr(u64 val, u64 mask)
> 
> The parameters of these differ in naming convention, order, and size,
> which is unfortunate. They also differ slightly in behaviour, as
> change_cpacr() skips the sysreg write if the bits are unchanged, which
> is a useful optimization when sysreg writes are expensive.
> 
> Before we gain more yet another sysreg manipulation function, let's
> unify these with a common helper, providing a consistent order for
> clear/set operands, and the write skipping behaviour from
> change_cpacr(). Code will be migrated to the new helper in subsequent
> patches.
> 
> Signed-off-by: Mark Rutland <mark.rutland@arm.com>
> Reviewed-by: Dave Martin <dave.martin@arm.com>
> Cc: Catalin Marinas <catalin.marinas@arm.com>
> Cc: Marc Zyngier <marc.zyngier@arm.com>

Acked-by: Catalin Marinas <catalin.marinas@arm.com>

^ permalink raw reply	[flat|nested] 53+ messages in thread

* Re: [PATCHv3 04/19] arm64: kill config_sctlr_el1()
  2018-06-18 12:02 ` [PATCHv3 04/19] arm64: kill config_sctlr_el1() Mark Rutland
@ 2018-06-19 11:44   ` Catalin Marinas
  0 siblings, 0 replies; 53+ messages in thread
From: Catalin Marinas @ 2018-06-19 11:44 UTC (permalink / raw)
  To: Mark Rutland
  Cc: linux-arm-kernel, will.deacon, marc.zyngier, linux, hch,
	james.morse, viro, linux-fsdevel, dave.martin

On Mon, Jun 18, 2018 at 01:02:55PM +0100, Mark Rutland wrote:
> Now that we have sysreg_clear_set(), we can consistently use this
> instead of config_sctlr_el1().
> 
> Signed-off-by: Mark Rutland <mark.rutland@arm.com>
> Reviewed-by: Dave Martin <dave.martin@arm.com>
> Cc: Catalin Marinas <catalin.marinas@arm.com>
> Cc: James Morse <james.morse@arm.com>
> Cc: Will Deacon <will.deacon@arm.com>

Acked-by: Catalin Marinas <catalin.marinas@arm.com>

^ permalink raw reply	[flat|nested] 53+ messages in thread

* Re: [PATCHv3 05/19] arm64: kill change_cpacr()
  2018-06-18 12:02 ` [PATCHv3 05/19] arm64: kill change_cpacr() Mark Rutland
@ 2018-06-19 11:45   ` Catalin Marinas
  0 siblings, 0 replies; 53+ messages in thread
From: Catalin Marinas @ 2018-06-19 11:45 UTC (permalink / raw)
  To: Mark Rutland
  Cc: linux-arm-kernel, will.deacon, marc.zyngier, linux, hch,
	james.morse, viro, linux-fsdevel, dave.martin

On Mon, Jun 18, 2018 at 01:02:56PM +0100, Mark Rutland wrote:
> Now that we have sysreg_clear_set(), we can use this instead of
> change_cpacr().
> 
> Note that the order of the set and clear arguments differs between
> change_cpacr() and sysreg_clear_set(), so these are flipped as part of
> the conversion. Also, sve_user_enable() redundantly clears
> CPACR_EL1_ZEN_EL0EN before setting it; this is removed for clarity.
> 
> Signed-off-by: Mark Rutland <mark.rutland@arm.com>
> Reviewed-by: Dave Martin <dave.martin@arm.com>
> Cc: Catalin Marinas <catalin.marinas@arm.com>
> Cc: James Morse <james.morse@arm.com>
> Cc: Will Deacon <will.deacon@arm.com>

Acked-by: Catalin Marinas <catalin.marinas@arm.com>

^ permalink raw reply	[flat|nested] 53+ messages in thread

* Re: [PATCHv3 03/19] arm64: introduce sysreg_clear_set()
  2018-06-18 12:02 ` [PATCHv3 03/19] arm64: introduce sysreg_clear_set() Mark Rutland
  2018-06-19 11:44   ` Catalin Marinas
@ 2018-06-19 11:47   ` Marc Zyngier
  1 sibling, 0 replies; 53+ messages in thread
From: Marc Zyngier @ 2018-06-19 11:47 UTC (permalink / raw)
  To: Mark Rutland, linux-arm-kernel, catalin.marinas, will.deacon
  Cc: dave.martin, hch, james.morse, linux, linux-fsdevel, viro

On 18/06/18 13:02, Mark Rutland wrote:
> Currently we have a couple of helpers to manipulate bits in particular
> sysregs:
> 
>  * config_sctlr_el1(u32 clear, u32 set)
> 
>  * change_cpacr(u64 val, u64 mask)
> 
> The parameters of these differ in naming convention, order, and size,
> which is unfortunate. They also differ slightly in behaviour, as
> change_cpacr() skips the sysreg write if the bits are unchanged, which
> is a useful optimization when sysreg writes are expensive.
> 
> Before we gain more yet another sysreg manipulation function, let's
> unify these with a common helper, providing a consistent order for
> clear/set operands, and the write skipping behaviour from
> change_cpacr(). Code will be migrated to the new helper in subsequent
> patches.
> 
> Signed-off-by: Mark Rutland <mark.rutland@arm.com>
> Reviewed-by: Dave Martin <dave.martin@arm.com>
> Cc: Catalin Marinas <catalin.marinas@arm.com>
> Cc: Marc Zyngier <marc.zyngier@arm.com>
> ---
>  arch/arm64/include/asm/sysreg.h | 11 +++++++++++
>  1 file changed, 11 insertions(+)
> 
> diff --git a/arch/arm64/include/asm/sysreg.h b/arch/arm64/include/asm/sysreg.h
> index 48ad361c178e..fefc17dae8ee 100644
> --- a/arch/arm64/include/asm/sysreg.h
> +++ b/arch/arm64/include/asm/sysreg.h
> @@ -731,6 +731,17 @@ asm(
>  	asm volatile("msr_s " __stringify(r) ", %x0" : : "rZ" (__val));	\
>  } while (0)
>  
> +/*
> + * Modify bits in a sysreg. Bits in the clear mask are zeroed, then bits in the
> + * set mask are set. Other bits are left as-is.
> + */
> +#define sysreg_clear_set(sysreg, clear, set) do {			\
> +	u64 __scs_val = read_sysreg(sysreg);				\
> +	u64 __scs_new = (__scs_val & ~(u64)(clear)) | (set);		\
> +	if (__scs_new != __scs_val)					\
> +		write_sysreg(__scs_new, sysreg);			\
> +} while (0)
> +
>  static inline void config_sctlr_el1(u32 clear, u32 set)
>  {
>  	u32 val;
> 

For the record, I have this patch as part of Dave's FPSIMD/SVE fixes.

Thanks,

	M.
-- 
Jazz is not dead. It just smells funny...

^ permalink raw reply	[flat|nested] 53+ messages in thread

* Re: [PATCHv3 02/19] arm64: move SCTLR_EL{1,2} assertions to <asm/sysreg.h>
  2018-06-18 12:02 ` [PATCHv3 02/19] arm64: move SCTLR_EL{1,2} assertions to <asm/sysreg.h> Mark Rutland
  2018-06-19 11:02   ` [PATCHv3 02/19] arm64: move SCTLR_EL{1, 2} " Catalin Marinas
@ 2018-06-19 11:48   ` Mark Rutland
  1 sibling, 0 replies; 53+ messages in thread
From: Mark Rutland @ 2018-06-19 11:48 UTC (permalink / raw)
  To: linux-arm-kernel, catalin.marinas, will.deacon
  Cc: dave.martin, hch, james.morse, linux, linux-fsdevel, marc.zyngier, viro

On Mon, Jun 18, 2018 at 01:02:53PM +0100, Mark Rutland wrote:
> Currently we assert that the SCTLR_EL{1,2}_{SET,CLEAR} bits are
> self-consistent with an assertion in config_sctlr_el1(). This is a bit
> unusual, since config_sctlr_el1() doesn't make use of these definitions,
> and is far away from the definitions themselves.
> 
> We can use the CPP #error directive to have equivalent assertions in
> <asm/sysreg.h>, next to the definitions of the set/clear bits, which is
> a bit clearer and simpler.
> 
> At the same time, lets fill in the upper 32 bits for both registers in
> their repsective RES0 definitions. This could be a little nicer with

Typo: s/repsective/respective/

I've fixed that up locally.

Mark.

^ permalink raw reply	[flat|nested] 53+ messages in thread

* Re: [PATCHv3 06/19] arm64: move sve_user_{enable, disable} to <asm/fpsimd.h>
  2018-06-18 12:02 ` [PATCHv3 06/19] arm64: move sve_user_{enable,disable} to <asm/fpsimd.h> Mark Rutland
@ 2018-06-19 12:00   ` Catalin Marinas
  2018-06-19 12:19   ` Dave Martin
  1 sibling, 0 replies; 53+ messages in thread
From: Catalin Marinas @ 2018-06-19 12:00 UTC (permalink / raw)
  To: Mark Rutland
  Cc: linux-arm-kernel, will.deacon, marc.zyngier, linux, hch,
	james.morse, viro, linux-fsdevel, dave.martin

On Mon, Jun 18, 2018 at 01:02:57PM +0100, Mark Rutland wrote:
> In subsequent patches, we'll want to make use of sve_user_enable() and
> sve_user_disable() outside of kernel/fpsimd.c. Let's move these to
> <asm/fpsimd.h> where we can make use of them.
> 
> To avoid ifdeffery in sequences like:
> 
> if (system_supports_sve() && some_condition
> 	sve_user_disable();
> 
> ... empty stubs are provided when support for SVE is not enabled. Note
> that system_supports_sve() contains as IS_ENABLED(CONFIG_ARM64_SVE), so
> the sve_user_disable() call should be optimized away entirely when
> CONFIG_ARM64_SVE is not selected.
> 
> To ensure that this is the case, the stub definitions contain a
> BUILD_BUG(), as we do for other stubs for which calls should always be
> optimized away when the relevant config option is not selected.
> 
> At the same time, the include list of <asm/fpsimd.h> is sorted while
> adding <asm/sysreg.h>.
> 
> Signed-off-by: Mark Rutland <mark.rutland@arm.com>
> Cc: Catalin Marinas <catalin.marinas@arm.com>
> Cc: Dave Martin <dave.martin@arm.com>
> Cc: Will Deacon <will.deacon@arm.com>

Acked-by: Catalin Marinas <catalin.marinas@arm.com>

^ permalink raw reply	[flat|nested] 53+ messages in thread

* Re: [PATCHv3 10/19] arm64: convert native/compat syscall entry to C
  2018-06-18 12:03 ` [PATCHv3 10/19] arm64: convert native/compat syscall entry " Mark Rutland
@ 2018-06-19 12:18   ` Dave Martin
  2018-06-19 13:15     ` Mark Rutland
  2018-06-19 15:20   ` Catalin Marinas
  1 sibling, 1 reply; 53+ messages in thread
From: Dave Martin @ 2018-06-19 12:18 UTC (permalink / raw)
  To: Mark Rutland
  Cc: marc.zyngier, catalin.marinas, will.deacon, linux, hch,
	james.morse, viro, linux-fsdevel, linux-arm-kernel

On Mon, Jun 18, 2018 at 01:03:01PM +0100, Mark Rutland wrote:
> Now that the syscall invocation logic is in C, we can migrate the rest
> of the syscall entry logic over, so that the entry assembly needn't look
> at the register values at all.
> 
> The SVE reset across syscall logic now unconditionally clears TIF_SVE,
> but sve_user_disable() will only write back to CPACR_EL1 when SVE is
> actually enabled.
> 
> Signed-off-by: Mark Rutland <mark.rutland@arm.com>
> Cc: Catalin Marinas <catalin.marinas@arm.com>
> Cc: Will Deacon <will.deacon@arm.com>
> ---
>  arch/arm64/kernel/entry.S   | 42 ++++--------------------------------------
>  arch/arm64/kernel/syscall.c | 40 ++++++++++++++++++++++++++++++++++++++--
>  2 files changed, 42 insertions(+), 40 deletions(-)
> 
> diff --git a/arch/arm64/kernel/entry.S b/arch/arm64/kernel/entry.S
> index 05b9f03f3e00..156c4e3fd1a4 100644
> --- a/arch/arm64/kernel/entry.S
> +++ b/arch/arm64/kernel/entry.S
> @@ -720,14 +720,9 @@ el0_sync_compat:
>  	b.ge	el0_dbg
>  	b	el0_inv
>  el0_svc_compat:
> -	/*
> -	 * AArch32 syscall handling
> -	 */
> -	ldr	x16, [tsk, #TSK_TI_FLAGS]	// load thread flags
> -	adrp	stbl, compat_sys_call_table	// load compat syscall table pointer
> -	mov	wscno, w7			// syscall number in w7 (r7)
> -	mov     wsc_nr, #__NR_compat_syscalls
> -	b	el0_svc_naked
> +	mov	x0, sp
> +	bl	el0_svc_compat_handler
> +	b	ret_to_user
>  
>  	.align	6
>  el0_irq_compat:
> @@ -925,37 +920,8 @@ ENDPROC(ret_to_user)
>   */
>  	.align	6
>  el0_svc:
> -	ldr	x16, [tsk, #TSK_TI_FLAGS]	// load thread flags
> -	adrp	stbl, sys_call_table		// load syscall table pointer
> -	mov	wscno, w8			// syscall number in w8
> -	mov	wsc_nr, #__NR_syscalls
> -
> -#ifdef CONFIG_ARM64_SVE
> -alternative_if_not ARM64_SVE
> -	b	el0_svc_naked
> -alternative_else_nop_endif
> -	tbz	x16, #TIF_SVE, el0_svc_naked	// Skip unless TIF_SVE set:
> -	bic	x16, x16, #_TIF_SVE		// discard SVE state
> -	str	x16, [tsk, #TSK_TI_FLAGS]
> -
> -	/*
> -	 * task_fpsimd_load() won't be called to update CPACR_EL1 in
> -	 * ret_to_user unless TIF_FOREIGN_FPSTATE is still set, which only
> -	 * happens if a context switch or kernel_neon_begin() or context
> -	 * modification (sigreturn, ptrace) intervenes.
> -	 * So, ensure that CPACR_EL1 is already correct for the fast-path case:
> -	 */
> -	mrs	x9, cpacr_el1
> -	bic	x9, x9, #CPACR_EL1_ZEN_EL0EN	// disable SVE for el0
> -	msr	cpacr_el1, x9			// synchronised by eret to el0
> -#endif
> -
> -el0_svc_naked:					// compat entry point
>  	mov	x0, sp
> -	mov	w1, wscno
> -	mov	w2, wsc_nr
> -	mov	x3, stbl
> -	bl	el0_svc_common
> +	bl	el0_svc_handler
>  	b	ret_to_user
>  ENDPROC(el0_svc)
>  
> diff --git a/arch/arm64/kernel/syscall.c b/arch/arm64/kernel/syscall.c
> index 2adf1a073398..6a31bb2a382b 100644
> --- a/arch/arm64/kernel/syscall.c
> +++ b/arch/arm64/kernel/syscall.c
> @@ -6,7 +6,9 @@
>  #include <linux/ptrace.h>
>  
>  #include <asm/daifflags.h>
> +#include <asm/fpsimd.h>
>  #include <asm/thread_info.h>
> +#include <asm/unistd.h>
>  
>  long do_ni_syscall(struct pt_regs *regs);
>  
> @@ -42,8 +44,8 @@ static inline bool has_syscall_work(unsigned long flags)
>  int syscall_trace_enter(struct pt_regs *regs);
>  void syscall_trace_exit(struct pt_regs *regs);
>  
> -asmlinkage void el0_svc_common(struct pt_regs *regs, int scno, int sc_nr,
> -			       syscall_fn_t syscall_table[])
> +static void el0_svc_common(struct pt_regs *regs, int scno, int sc_nr,
> +			   syscall_fn_t syscall_table[])
>  {
>  	unsigned long flags = current_thread_info()->flags;
>  
> @@ -80,3 +82,37 @@ asmlinkage void el0_svc_common(struct pt_regs *regs, int scno, int sc_nr,
>  trace_exit:
>  	syscall_trace_exit(regs);
>  }
> +
> +static inline void sve_user_reset(void)
> +{

Can we call this "sve_user_discard" please?

"Reset" is a reasonable name for the concept, but the "discard"
terminology has been used elsewhere.

> +	if (!system_supports_sve())
> +		return;
> +
> +	/*
> +	 * task_fpsimd_load() won't be called to update CPACR_EL1 in
> +	 * ret_to_user unless TIF_FOREIGN_FPSTATE is still set, which only
> +	 * happens if a context switch or kernel_neon_begin() or context
> +	 * modification (sigreturn, ptrace) intervenes.
> +	 * So, ensure that CPACR_EL1 is already correct for the fast-path case.
> +	 */

This comment should go after clear_thead_flag(), since it describes not
the purpose of this function but the presence of sve_user_disable().

> +	clear_thread_flag(TIF_SVE);
> +	sve_user_disable();
> +}
> +
> +extern syscall_fn_t sys_call_table[];
> +
> +asmlinkage void el0_svc_handler(struct pt_regs *regs)
> +{
> +	sve_user_reset();
> +	el0_svc_common(regs, regs->regs[8], __NR_syscalls, sys_call_table);
> +}
> +
> +#ifdef CONFIG_COMPAT
> +extern syscall_fn_t compat_sys_call_table[];
> +
> +asmlinkage void el0_svc_compat_handler(struct pt_regs *regs)
> +{
> +	el0_svc_common(regs, regs->regs[7], __NR_compat_syscalls,
> +		       compat_sys_call_table);
> +}
> +#endif
> -- 
> 2.11.0
> 
> 
> _______________________________________________
> linux-arm-kernel mailing list
> linux-arm-kernel@lists.infradead.org
> http://lists.infradead.org/mailman/listinfo/linux-arm-kernel

^ permalink raw reply	[flat|nested] 53+ messages in thread

* Re: [PATCHv3 06/19] arm64: move sve_user_{enable, disable} to <asm/fpsimd.h>
  2018-06-18 12:02 ` [PATCHv3 06/19] arm64: move sve_user_{enable,disable} to <asm/fpsimd.h> Mark Rutland
  2018-06-19 12:00   ` [PATCHv3 06/19] arm64: move sve_user_{enable, disable} " Catalin Marinas
@ 2018-06-19 12:19   ` Dave Martin
  1 sibling, 0 replies; 53+ messages in thread
From: Dave Martin @ 2018-06-19 12:19 UTC (permalink / raw)
  To: Mark Rutland
  Cc: linux-arm-kernel, catalin.marinas, will.deacon, marc.zyngier,
	linux, hch, james.morse, viro, linux-fsdevel

On Mon, Jun 18, 2018 at 01:02:57PM +0100, Mark Rutland wrote:
> In subsequent patches, we'll want to make use of sve_user_enable() and
> sve_user_disable() outside of kernel/fpsimd.c. Let's move these to
> <asm/fpsimd.h> where we can make use of them.
> 
> To avoid ifdeffery in sequences like:
> 
> if (system_supports_sve() && some_condition
> 	sve_user_disable();
> 
> ... empty stubs are provided when support for SVE is not enabled. Note
> that system_supports_sve() contains as IS_ENABLED(CONFIG_ARM64_SVE), so
> the sve_user_disable() call should be optimized away entirely when
> CONFIG_ARM64_SVE is not selected.
> 
> To ensure that this is the case, the stub definitions contain a
> BUILD_BUG(), as we do for other stubs for which calls should always be
> optimized away when the relevant config option is not selected.
> 
> At the same time, the include list of <asm/fpsimd.h> is sorted while
> adding <asm/sysreg.h>.
> 
> Signed-off-by: Mark Rutland <mark.rutland@arm.com>
> Cc: Catalin Marinas <catalin.marinas@arm.com>
> Cc: Dave Martin <dave.martin@arm.com>
> Cc: Will Deacon <will.deacon@arm.com>

Reviewed-by: Dave Martin <Dave.Martin@arm.com>

> ---
>  arch/arm64/include/asm/fpsimd.h | 17 ++++++++++++++++-
>  arch/arm64/kernel/fpsimd.c      | 10 ----------
>  2 files changed, 16 insertions(+), 11 deletions(-)
> 
> diff --git a/arch/arm64/include/asm/fpsimd.h b/arch/arm64/include/asm/fpsimd.h
> index fa92747a49c8..dd1ad3950ef5 100644
> --- a/arch/arm64/include/asm/fpsimd.h
> +++ b/arch/arm64/include/asm/fpsimd.h
> @@ -16,13 +16,15 @@
>  #ifndef __ASM_FP_H
>  #define __ASM_FP_H
>  
> -#include <asm/ptrace.h>
>  #include <asm/errno.h>
> +#include <asm/ptrace.h>
>  #include <asm/processor.h>
>  #include <asm/sigcontext.h>
> +#include <asm/sysreg.h>
>  
>  #ifndef __ASSEMBLY__
>  
> +#include <linux/build_bug.h>
>  #include <linux/cache.h>
>  #include <linux/init.h>
>  #include <linux/stddef.h>
> @@ -102,6 +104,16 @@ extern int sve_set_vector_length(struct task_struct *task,
>  extern int sve_set_current_vl(unsigned long arg);
>  extern int sve_get_current_vl(void);
>  
> +static inline void sve_user_disable(void)
> +{
> +	sysreg_clear_set(cpacr_el1, CPACR_EL1_ZEN_EL0EN, 0);
> +}
> +
> +static inline void sve_user_enable(void)
> +{
> +	sysreg_clear_set(cpacr_el1, 0, CPACR_EL1_ZEN_EL0EN);
> +}
> +
>  /*
>   * Probing and setup functions.
>   * Calls to these functions must be serialised with one another.
> @@ -128,6 +140,9 @@ static inline int sve_get_current_vl(void)
>  	return -EINVAL;
>  }
>  
> +static inline void sve_user_disable(void) { BUILD_BUG(); }
> +static inline void sve_user_enable(void) { BUILD_BUG(); }
> +
>  static inline void sve_init_vq_map(void) { }
>  static inline void sve_update_vq_map(void) { }
>  static inline int sve_verify_vq_map(void) { return 0; }
> diff --git a/arch/arm64/kernel/fpsimd.c b/arch/arm64/kernel/fpsimd.c
> index a98a7f96aff1..58c53bc96928 100644
> --- a/arch/arm64/kernel/fpsimd.c
> +++ b/arch/arm64/kernel/fpsimd.c
> @@ -159,16 +159,6 @@ static void sve_free(struct task_struct *task)
>  	__sve_free(task);
>  }
>  
> -static void sve_user_disable(void)
> -{
> -	sysreg_clear_set(cpacr_el1, CPACR_EL1_ZEN_EL0EN, 0);
> -}
> -
> -static void sve_user_enable(void)
> -{
> -	sysreg_clear_set(cpacr_el1, 0, CPACR_EL1_ZEN_EL0EN);
> -}
> -
>  /*
>   * TIF_SVE controls whether a task can use SVE without trapping while
>   * in userspace, and also the way a task's FPSIMD/SVE state is stored
> -- 
> 2.11.0
> 
> 
> _______________________________________________
> linux-arm-kernel mailing list
> linux-arm-kernel@lists.infradead.org
> http://lists.infradead.org/mailman/listinfo/linux-arm-kernel

^ permalink raw reply	[flat|nested] 53+ messages in thread

* Re: [PATCHv3 07/19] arm64: remove sigreturn wrappers
  2018-06-18 12:02 ` [PATCHv3 07/19] arm64: remove sigreturn wrappers Mark Rutland
@ 2018-06-19 12:47   ` Catalin Marinas
  0 siblings, 0 replies; 53+ messages in thread
From: Catalin Marinas @ 2018-06-19 12:47 UTC (permalink / raw)
  To: Mark Rutland
  Cc: linux-arm-kernel, will.deacon, marc.zyngier, linux, hch,
	james.morse, viro, linux-fsdevel, dave.martin

On Mon, Jun 18, 2018 at 01:02:58PM +0100, Mark Rutland wrote:
> The arm64 sigreturn* syscall handlers are non-standard. Rather than
> taking a number of user parameters in registers as per the AAPCS,
> they expect the pt_regs as their sole argument.
> 
> To make this work, we override the syscall definitions to invoke
> wrappers written in assembly, which mov the SP into x0, and branch to
> their respective C functions.
> 
> On other architectures (such as x86), the sigreturn* functions take no
> argument and instead use current_pt_regs() to acquire the user
> registers. This requires less boilerplate code, and allows for other
> features such as interposing C code in this path.
> 
> This patch takes the same approach for arm64.
> 
> Signed-off-by: Mark Rutland <mark.rutland@arm.com>
> Tentatively-reviewed-by: Dave Martin <dave.martin@arm.com>
> Cc: Catalin Marinas <catalin.marinas@arm.com>
> Cc: Will Deacon <will.deacon@arm.com>

Reviewed-by: Catalin Marinas <catalin.marinas@arm.com>

^ permalink raw reply	[flat|nested] 53+ messages in thread

* Re: [PATCHv3 10/19] arm64: convert native/compat syscall entry to C
  2018-06-19 12:18   ` Dave Martin
@ 2018-06-19 13:15     ` Mark Rutland
  2018-06-20  9:21       ` Dave Martin
  0 siblings, 1 reply; 53+ messages in thread
From: Mark Rutland @ 2018-06-19 13:15 UTC (permalink / raw)
  To: Dave Martin
  Cc: linux-arm-kernel, catalin.marinas, will.deacon, marc.zyngier,
	linux, hch, james.morse, viro, linux-fsdevel

On Tue, Jun 19, 2018 at 01:18:17PM +0100, Dave Martin wrote:
> On Mon, Jun 18, 2018 at 01:03:01PM +0100, Mark Rutland wrote:
> > +static inline void sve_user_reset(void)
> > +{
> 
> Can we call this "sve_user_discard" please?
> 
> "Reset" is a reasonable name for the concept, but the "discard"
> terminology has been used elsewhere.

Sure; done.

> > +	if (!system_supports_sve())
> > +		return;
> > +
> > +	/*
> > +	 * task_fpsimd_load() won't be called to update CPACR_EL1 in
> > +	 * ret_to_user unless TIF_FOREIGN_FPSTATE is still set, which only
> > +	 * happens if a context switch or kernel_neon_begin() or context
> > +	 * modification (sigreturn, ptrace) intervenes.
> > +	 * So, ensure that CPACR_EL1 is already correct for the fast-path case.
> > +	 */
> 
> This comment should go after clear_thead_flag(), since it describes not
> the purpose of this function but the presence of sve_user_disable().
> 
> > +	clear_thread_flag(TIF_SVE);
> > +	sve_user_disable();
> > +}

Good point. I've moved the clear_thread_flag(TIF_SVE) above the comment
(with a blank line before the comment).

Thanks,
Mark.

^ permalink raw reply	[flat|nested] 53+ messages in thread

* Re: [PATCHv3 08/19] arm64: convert raw syscall invocation to C
  2018-06-18 12:02 ` [PATCHv3 08/19] arm64: convert raw syscall invocation to C Mark Rutland
@ 2018-06-19 13:33   ` Catalin Marinas
  2018-06-19 14:21   ` Catalin Marinas
  1 sibling, 0 replies; 53+ messages in thread
From: Catalin Marinas @ 2018-06-19 13:33 UTC (permalink / raw)
  To: Mark Rutland
  Cc: linux-arm-kernel, will.deacon, marc.zyngier, linux, hch,
	james.morse, viro, linux-fsdevel, dave.martin

On Mon, Jun 18, 2018 at 01:02:59PM +0100, Mark Rutland wrote:
> As a first step towards invoking syscalls with a pt_regs argument,
> convert the raw syscall invocation logic to C. We end up with a bit more
> register shuffling, but the unified invocation logic means we can unify
> the tracing paths, too.
> 
> Previously, assembly had to open-code calls to ni_sys() when the system
> call number was out-of-bounds for the relevant syscall table. This case
> is now handled by invoke_syscall(), and the assembly no longer need to
> handle this case explicitly. This allows the tracing paths to be
> simplfiied and unified, as we no longer need the __ni_sys_trace path and

'simplified'

> the __sys_trace_return label.
> 
> This only converts the invocation of the syscall. The rest of the
> syscall triage and tracing is left in assembly for now, and will be
> converted in subsequent patches.
> 
> Signed-off-by: Mark Rutland <mark.rutland@arm.com>
> Cc: Catalin Marinas <catalin.marinas@arm.com>
> Cc: Will Deacon <will.deacon@arm.com>

Reviewed-by: Catalin Marinas <catalin.marinas@arm.com>

^ permalink raw reply	[flat|nested] 53+ messages in thread

* Re: [PATCHv3 08/19] arm64: convert raw syscall invocation to C
  2018-06-18 12:02 ` [PATCHv3 08/19] arm64: convert raw syscall invocation to C Mark Rutland
  2018-06-19 13:33   ` Catalin Marinas
@ 2018-06-19 14:21   ` Catalin Marinas
  2018-06-19 14:48     ` Mark Rutland
  1 sibling, 1 reply; 53+ messages in thread
From: Catalin Marinas @ 2018-06-19 14:21 UTC (permalink / raw)
  To: Mark Rutland
  Cc: linux-arm-kernel, will.deacon, marc.zyngier, linux, hch,
	james.morse, viro, linux-fsdevel, dave.martin

On Mon, Jun 18, 2018 at 01:02:59PM +0100, Mark Rutland wrote:
> diff --git a/arch/arm64/kernel/syscall.c b/arch/arm64/kernel/syscall.c
> new file mode 100644
> index 000000000000..b463b962d597
> --- /dev/null
> +++ b/arch/arm64/kernel/syscall.c
> @@ -0,0 +1,30 @@
> +// SPDX-License-Identifier: GPL-2.0
> +
> +#include <linux/nospec.h>
> +#include <linux/ptrace.h>
> +
> +long do_ni_syscall(struct pt_regs *regs);
> +
> +typedef long (*syscall_fn_t)(unsigned long, unsigned long,
> +			     unsigned long, unsigned long,
> +			     unsigned long, unsigned long);
> +
> +static void __invoke_syscall(struct pt_regs *regs, syscall_fn_t syscall_fn)
> +{
> +	regs->regs[0] = syscall_fn(regs->regs[0], regs->regs[1],
> +				   regs->regs[2], regs->regs[3],
> +				   regs->regs[4], regs->regs[5]);
> +}
> +
> +asmlinkage void invoke_syscall(struct pt_regs *regs, unsigned int scno,
> +			       unsigned int sc_nr,
> +			       syscall_fn_t syscall_table[])
> +{
> +	if (scno < sc_nr) {
> +		syscall_fn_t syscall_fn;
> +		syscall_fn = syscall_table[array_index_nospec(scno, sc_nr)];
> +		__invoke_syscall(regs, syscall_fn);
> +	} else {
> +		regs->regs[0] = do_ni_syscall(regs);
> +	}
> +}

While reviewing the subsequent patch, it crossed my mind that we no
longer have any callers to do_ni_syscall() outside this file. Can we not
more it here and have a similar implementation to __invoke_syscall() for
consistency, i.e. set regs->regs[0].

-- 
Catalin

^ permalink raw reply	[flat|nested] 53+ messages in thread

* Re: [PATCHv3 09/19] arm64: convert syscall trace logic to C
  2018-06-18 12:03 ` [PATCHv3 09/19] arm64: convert syscall trace logic " Mark Rutland
@ 2018-06-19 14:32   ` Catalin Marinas
  2018-06-19 15:14     ` Mark Rutland
  0 siblings, 1 reply; 53+ messages in thread
From: Catalin Marinas @ 2018-06-19 14:32 UTC (permalink / raw)
  To: Mark Rutland
  Cc: linux-arm-kernel, will.deacon, marc.zyngier, linux, hch,
	james.morse, viro, linux-fsdevel, dave.martin

On Mon, Jun 18, 2018 at 01:03:00PM +0100, Mark Rutland wrote:
> +asmlinkage void el0_svc_common(struct pt_regs *regs, int scno, int sc_nr,
> +			       syscall_fn_t syscall_table[])
> +{
> +	unsigned long flags = current_thread_info()->flags;
> +
> +	regs->orig_x0 = regs->regs[0];
> +	regs->syscallno = scno;
> +
> +	local_daif_restore(DAIF_PROCCTX);
> +	user_exit();
> +
> +	if (has_syscall_work(flags)) {
> +		/* set default errno for user-issued syscall(-1) */
> +		if (scno == NO_SYSCALL)
> +			regs->regs[0] = -ENOSYS;
> +		scno = syscall_trace_enter(regs);
> +		if (scno == NO_SYSCALL)
> +			goto trace_exit;
> +	}
> +
> +	invoke_syscall(regs, scno, sc_nr, syscall_table);
> +
> +	/*
> +	 * The tracing status may have changed under our feet, so we have to
> +	 * check again. However, if we were tracing entry, then we always trace
> +	 * exit regardless, as the old entry assembly did.
> +	 */
> +	if (!has_syscall_work(flags)) {
> +		local_daif_mask();
> +		flags = current_thread_info()->flags;
> +		if (!has_syscall_work(flags))
> +			return;
> +		local_daif_restore(DAIF_PROCCTX);
> +	}

IIUC the above 'if' block replaces ret_fast_syscall in entry.S with the
work_pending handled via ret_to_user (we used to check _TIF_WORK_MASK in
two places). 

Reviewed-by: Catalin Marinas <catalin.marinas@arm.com>

^ permalink raw reply	[flat|nested] 53+ messages in thread

* Re: [PATCHv3 08/19] arm64: convert raw syscall invocation to C
  2018-06-19 14:21   ` Catalin Marinas
@ 2018-06-19 14:48     ` Mark Rutland
  2018-06-19 14:55       ` Catalin Marinas
  0 siblings, 1 reply; 53+ messages in thread
From: Mark Rutland @ 2018-06-19 14:48 UTC (permalink / raw)
  To: Catalin Marinas
  Cc: linux-arm-kernel, will.deacon, marc.zyngier, linux, hch,
	james.morse, viro, linux-fsdevel, dave.martin

On Tue, Jun 19, 2018 at 03:21:25PM +0100, Catalin Marinas wrote:
> On Mon, Jun 18, 2018 at 01:02:59PM +0100, Mark Rutland wrote:
> > diff --git a/arch/arm64/kernel/syscall.c b/arch/arm64/kernel/syscall.c
> > new file mode 100644
> > index 000000000000..b463b962d597
> > --- /dev/null
> > +++ b/arch/arm64/kernel/syscall.c
> > @@ -0,0 +1,30 @@
> > +// SPDX-License-Identifier: GPL-2.0
> > +
> > +#include <linux/nospec.h>
> > +#include <linux/ptrace.h>
> > +
> > +long do_ni_syscall(struct pt_regs *regs);
> > +
> > +typedef long (*syscall_fn_t)(unsigned long, unsigned long,
> > +			     unsigned long, unsigned long,
> > +			     unsigned long, unsigned long);
> > +
> > +static void __invoke_syscall(struct pt_regs *regs, syscall_fn_t syscall_fn)
> > +{
> > +	regs->regs[0] = syscall_fn(regs->regs[0], regs->regs[1],
> > +				   regs->regs[2], regs->regs[3],
> > +				   regs->regs[4], regs->regs[5]);
> > +}
> > +
> > +asmlinkage void invoke_syscall(struct pt_regs *regs, unsigned int scno,
> > +			       unsigned int sc_nr,
> > +			       syscall_fn_t syscall_table[])
> > +{
> > +	if (scno < sc_nr) {
> > +		syscall_fn_t syscall_fn;
> > +		syscall_fn = syscall_table[array_index_nospec(scno, sc_nr)];
> > +		__invoke_syscall(regs, syscall_fn);
> > +	} else {
> > +		regs->regs[0] = do_ni_syscall(regs);
> > +	}
> > +}
> 
> While reviewing the subsequent patch, it crossed my mind that we no
> longer have any callers to do_ni_syscall() outside this file. Can we not
> more it here and have a similar implementation to __invoke_syscall() for
> consistency, i.e. set regs->regs[0].

I think so, though it complicates the logic in do_ni_syscall(), since
there are two places we may return a value.

Would you be happy if instead I made __invoke_syscall() return the
result, and have invoke_syscall() place the result in regs->regs[0] in
either case, e.g. as below?

Thanks,
Mark.

---->8----
// SPDX-License-Identifier: GPL-2.0

#include <linux/errno.h>
#include <linux/nospec.h>
#include <linux/ptrace.h>
#include <linux/syscalls.h>

#include <asm/compat.h>

long compat_arm_syscall(struct pt_regs *regs);

static long do_ni_syscall(struct pt_regs *regs)
{
#ifdef CONFIG_COMPAT
	long ret;
	if (is_compat_task()) {
		ret = compat_arm_syscall(regs);
		if (ret != -ENOSYS)
			return ret;
	}
#endif

	return sys_ni_syscall();
}

typedef long (*syscall_fn_t)(unsigned long, unsigned long,
			     unsigned long, unsigned long,
			     unsigned long, unsigned long);

static long __invoke_syscall(struct pt_regs *regs, syscall_fn_t syscall_fn)
{
	return syscall_fn(regs->regs[0], regs->regs[1], regs->regs[2],
			  regs->regs[3], regs->regs[4], regs->regs[5]);
}

asmlinkage void invoke_syscall(struct pt_regs *regs, unsigned int scno,
			       unsigned int sc_nr,
			       syscall_fn_t syscall_table[])
{
	long ret;

	if (scno < sc_nr) {
		syscall_fn_t syscall_fn;
		syscall_fn = syscall_table[array_index_nospec(scno, sc_nr)];
		ret = __invoke_syscall(regs, syscall_fn);
	} else {
		ret = do_ni_syscall(regs);
	}

	regs->regs[0] = ret;
}

^ permalink raw reply	[flat|nested] 53+ messages in thread

* Re: [PATCHv3 08/19] arm64: convert raw syscall invocation to C
  2018-06-19 14:48     ` Mark Rutland
@ 2018-06-19 14:55       ` Catalin Marinas
  2018-06-19 14:58         ` Mark Rutland
  0 siblings, 1 reply; 53+ messages in thread
From: Catalin Marinas @ 2018-06-19 14:55 UTC (permalink / raw)
  To: Mark Rutland
  Cc: marc.zyngier, will.deacon, linux, hch, james.morse, viro,
	linux-fsdevel, dave.martin, linux-arm-kernel

On Tue, Jun 19, 2018 at 03:48:45PM +0100, Mark Rutland wrote:
> On Tue, Jun 19, 2018 at 03:21:25PM +0100, Catalin Marinas wrote:
> > On Mon, Jun 18, 2018 at 01:02:59PM +0100, Mark Rutland wrote:
> > > diff --git a/arch/arm64/kernel/syscall.c b/arch/arm64/kernel/syscall.c
> > > new file mode 100644
> > > index 000000000000..b463b962d597
> > > --- /dev/null
> > > +++ b/arch/arm64/kernel/syscall.c
> > > @@ -0,0 +1,30 @@
> > > +// SPDX-License-Identifier: GPL-2.0
> > > +
> > > +#include <linux/nospec.h>
> > > +#include <linux/ptrace.h>
> > > +
> > > +long do_ni_syscall(struct pt_regs *regs);
> > > +
> > > +typedef long (*syscall_fn_t)(unsigned long, unsigned long,
> > > +			     unsigned long, unsigned long,
> > > +			     unsigned long, unsigned long);
> > > +
> > > +static void __invoke_syscall(struct pt_regs *regs, syscall_fn_t syscall_fn)
> > > +{
> > > +	regs->regs[0] = syscall_fn(regs->regs[0], regs->regs[1],
> > > +				   regs->regs[2], regs->regs[3],
> > > +				   regs->regs[4], regs->regs[5]);
> > > +}
> > > +
> > > +asmlinkage void invoke_syscall(struct pt_regs *regs, unsigned int scno,
> > > +			       unsigned int sc_nr,
> > > +			       syscall_fn_t syscall_table[])
> > > +{
> > > +	if (scno < sc_nr) {
> > > +		syscall_fn_t syscall_fn;
> > > +		syscall_fn = syscall_table[array_index_nospec(scno, sc_nr)];
> > > +		__invoke_syscall(regs, syscall_fn);
> > > +	} else {
> > > +		regs->regs[0] = do_ni_syscall(regs);
> > > +	}
> > > +}
> > 
> > While reviewing the subsequent patch, it crossed my mind that we no
> > longer have any callers to do_ni_syscall() outside this file. Can we not
> > more it here and have a similar implementation to __invoke_syscall() for
> > consistency, i.e. set regs->regs[0].
> 
> I think so, though it complicates the logic in do_ni_syscall(), since
> there are two places we may return a value.
> 
> Would you be happy if instead I made __invoke_syscall() return the
> result, and have invoke_syscall() place the result in regs->regs[0] in
> either case, e.g. as below?

It looks fine. Feel free to keep the original reviewed-by tag.

-- 
Catalin

^ permalink raw reply	[flat|nested] 53+ messages in thread

* Re: [PATCHv3 08/19] arm64: convert raw syscall invocation to C
  2018-06-19 14:55       ` Catalin Marinas
@ 2018-06-19 14:58         ` Mark Rutland
  0 siblings, 0 replies; 53+ messages in thread
From: Mark Rutland @ 2018-06-19 14:58 UTC (permalink / raw)
  To: Catalin Marinas
  Cc: marc.zyngier, will.deacon, linux, hch, james.morse, viro,
	linux-fsdevel, dave.martin, linux-arm-kernel

On Tue, Jun 19, 2018 at 03:55:42PM +0100, Catalin Marinas wrote:
> On Tue, Jun 19, 2018 at 03:48:45PM +0100, Mark Rutland wrote:
> > On Tue, Jun 19, 2018 at 03:21:25PM +0100, Catalin Marinas wrote:
> > > On Mon, Jun 18, 2018 at 01:02:59PM +0100, Mark Rutland wrote:
> > > > diff --git a/arch/arm64/kernel/syscall.c b/arch/arm64/kernel/syscall.c
> > > > new file mode 100644
> > > > index 000000000000..b463b962d597
> > > > --- /dev/null
> > > > +++ b/arch/arm64/kernel/syscall.c
> > > > @@ -0,0 +1,30 @@
> > > > +// SPDX-License-Identifier: GPL-2.0
> > > > +
> > > > +#include <linux/nospec.h>
> > > > +#include <linux/ptrace.h>
> > > > +
> > > > +long do_ni_syscall(struct pt_regs *regs);
> > > > +
> > > > +typedef long (*syscall_fn_t)(unsigned long, unsigned long,
> > > > +			     unsigned long, unsigned long,
> > > > +			     unsigned long, unsigned long);
> > > > +
> > > > +static void __invoke_syscall(struct pt_regs *regs, syscall_fn_t syscall_fn)
> > > > +{
> > > > +	regs->regs[0] = syscall_fn(regs->regs[0], regs->regs[1],
> > > > +				   regs->regs[2], regs->regs[3],
> > > > +				   regs->regs[4], regs->regs[5]);
> > > > +}
> > > > +
> > > > +asmlinkage void invoke_syscall(struct pt_regs *regs, unsigned int scno,
> > > > +			       unsigned int sc_nr,
> > > > +			       syscall_fn_t syscall_table[])
> > > > +{
> > > > +	if (scno < sc_nr) {
> > > > +		syscall_fn_t syscall_fn;
> > > > +		syscall_fn = syscall_table[array_index_nospec(scno, sc_nr)];
> > > > +		__invoke_syscall(regs, syscall_fn);
> > > > +	} else {
> > > > +		regs->regs[0] = do_ni_syscall(regs);
> > > > +	}
> > > > +}
> > > 
> > > While reviewing the subsequent patch, it crossed my mind that we no
> > > longer have any callers to do_ni_syscall() outside this file. Can we not
> > > more it here and have a similar implementation to __invoke_syscall() for
> > > consistency, i.e. set regs->regs[0].
> > 
> > I think so, though it complicates the logic in do_ni_syscall(), since
> > there are two places we may return a value.
> > 
> > Would you be happy if instead I made __invoke_syscall() return the
> > result, and have invoke_syscall() place the result in regs->regs[0] in
> > either case, e.g. as below?
> 
> It looks fine. Feel free to keep the original reviewed-by tag.

Will do; cheers!

Mark.

^ permalink raw reply	[flat|nested] 53+ messages in thread

* Re: [PATCHv3 09/19] arm64: convert syscall trace logic to C
  2018-06-19 14:32   ` Catalin Marinas
@ 2018-06-19 15:14     ` Mark Rutland
  0 siblings, 0 replies; 53+ messages in thread
From: Mark Rutland @ 2018-06-19 15:14 UTC (permalink / raw)
  To: Catalin Marinas
  Cc: linux-arm-kernel, will.deacon, marc.zyngier, linux, hch,
	james.morse, viro, linux-fsdevel, dave.martin

On Tue, Jun 19, 2018 at 03:32:45PM +0100, Catalin Marinas wrote:
> On Mon, Jun 18, 2018 at 01:03:00PM +0100, Mark Rutland wrote:
> > +asmlinkage void el0_svc_common(struct pt_regs *regs, int scno, int sc_nr,
> > +			       syscall_fn_t syscall_table[])
> > +{
> > +	unsigned long flags = current_thread_info()->flags;
> > +
> > +	regs->orig_x0 = regs->regs[0];
> > +	regs->syscallno = scno;
> > +
> > +	local_daif_restore(DAIF_PROCCTX);
> > +	user_exit();
> > +
> > +	if (has_syscall_work(flags)) {
> > +		/* set default errno for user-issued syscall(-1) */
> > +		if (scno == NO_SYSCALL)
> > +			regs->regs[0] = -ENOSYS;
> > +		scno = syscall_trace_enter(regs);
> > +		if (scno == NO_SYSCALL)
> > +			goto trace_exit;
> > +	}
> > +
> > +	invoke_syscall(regs, scno, sc_nr, syscall_table);
> > +
> > +	/*
> > +	 * The tracing status may have changed under our feet, so we have to
> > +	 * check again. However, if we were tracing entry, then we always trace
> > +	 * exit regardless, as the old entry assembly did.
> > +	 */
> > +	if (!has_syscall_work(flags)) {
> > +		local_daif_mask();
> > +		flags = current_thread_info()->flags;
> > +		if (!has_syscall_work(flags))
> > +			return;
> > +		local_daif_restore(DAIF_PROCCTX);
> > +	}
> 
> IIUC the above 'if' block replaces ret_fast_syscall in entry.S with the
> work_pending handled via ret_to_user (we used to check _TIF_WORK_MASK in
> two places). 

Yes. This replaces the _TIF_SYSCALL_WORK check from ret_fast_syscall,
leaving the _TIF_WORK_MASK check to the usual ret_to_user path.

> Reviewed-by: Catalin Marinas <catalin.marinas@arm.com>

Thanks!
Mark.

^ permalink raw reply	[flat|nested] 53+ messages in thread

* Re: [PATCHv3 10/19] arm64: convert native/compat syscall entry to C
  2018-06-18 12:03 ` [PATCHv3 10/19] arm64: convert native/compat syscall entry " Mark Rutland
  2018-06-19 12:18   ` Dave Martin
@ 2018-06-19 15:20   ` Catalin Marinas
  1 sibling, 0 replies; 53+ messages in thread
From: Catalin Marinas @ 2018-06-19 15:20 UTC (permalink / raw)
  To: Mark Rutland
  Cc: linux-arm-kernel, will.deacon, marc.zyngier, linux, hch,
	james.morse, viro, linux-fsdevel, dave.martin

On Mon, Jun 18, 2018 at 01:03:01PM +0100, Mark Rutland wrote:
> Now that the syscall invocation logic is in C, we can migrate the rest
> of the syscall entry logic over, so that the entry assembly needn't look
> at the register values at all.
> 
> The SVE reset across syscall logic now unconditionally clears TIF_SVE,
> but sve_user_disable() will only write back to CPACR_EL1 when SVE is
> actually enabled.
> 
> Signed-off-by: Mark Rutland <mark.rutland@arm.com>
> Cc: Catalin Marinas <catalin.marinas@arm.com>
> Cc: Will Deacon <will.deacon@arm.com>

Other than Dave's comments, it looks fine to me.

Reviewed-by: Catalin Marinas <catalin.marinas@arm.com>

^ permalink raw reply	[flat|nested] 53+ messages in thread

* Re: [PATCHv3 11/19] arm64: don't reload GPRs after apply_ssbd
  2018-06-18 12:03 ` [PATCHv3 11/19] arm64: don't reload GPRs after apply_ssbd Mark Rutland
@ 2018-06-19 15:23   ` Catalin Marinas
  0 siblings, 0 replies; 53+ messages in thread
From: Catalin Marinas @ 2018-06-19 15:23 UTC (permalink / raw)
  To: Mark Rutland
  Cc: linux-arm-kernel, will.deacon, marc.zyngier, linux, hch,
	james.morse, viro, linux-fsdevel, dave.martin

On Mon, Jun 18, 2018 at 01:03:02PM +0100, Mark Rutland wrote:
> Now that all of the syscall logic works on the saved pt_regs, apply_ssbd
> can safely corrupt x0-x3 in the entry paths, and we no longer need to
> restore them. So let's remove the logic doing so.
> 
> With that logic gone, we can fold the branch target into the macro, so
> that callers need not deal with this. GAS provides \@, which provides a
> unique value per macro invocation, which we can use to create a unique
> label.
> 
> Signed-off-by: Mark Rutland <mark.rutland@arm.com>
> Acked-by: Marc Zyngier <marc.zyngier@arm.com>
> Cc: Catalin Marinas <catalin.marinas@arm.com>
> Cc: Will Deacon <will.deacon@arm.com>

Acked-by: Catalin Marinas <catalin.marinas@arm.com>

^ permalink raw reply	[flat|nested] 53+ messages in thread

* Re: [PATCHv3 12/19] arm64: zero GPRs upon entry from EL0
  2018-06-18 12:03 ` [PATCHv3 12/19] arm64: zero GPRs upon entry from EL0 Mark Rutland
@ 2018-06-19 15:24   ` Catalin Marinas
  0 siblings, 0 replies; 53+ messages in thread
From: Catalin Marinas @ 2018-06-19 15:24 UTC (permalink / raw)
  To: Mark Rutland
  Cc: linux-arm-kernel, will.deacon, marc.zyngier, linux, hch,
	james.morse, viro, linux-fsdevel, dave.martin

On Mon, Jun 18, 2018 at 01:03:03PM +0100, Mark Rutland wrote:
> We can zero GPRs x0 - x29 upon entry from EL0 to make it harder for
> userspace to control values consumed by speculative gadgets.
> 
> We don't blat x30, since this is stashed much later, and we'll blat it
> before invoking C code.
> 
> Signed-off-by: Mark Rutland <mark.rutland@arm.com>
> Cc: Catalin Marinas <catalin.marinas@arm.com>
> Cc: Will Deacon <will.deacon@arm.com>

Acked-by: Catalin Marinas <catalin.marinas@arm.com>

^ permalink raw reply	[flat|nested] 53+ messages in thread

* Re: [PATCHv3 00/19] arm64: invoke syscalls with pt_regs
  2018-06-18 12:02 [PATCHv3 00/19] arm64: invoke syscalls with pt_regs Mark Rutland
                   ` (18 preceding siblings ...)
  2018-06-18 12:03 ` [PATCHv3 19/19] arm64: implement syscall wrappers Mark Rutland
@ 2018-06-19 15:38 ` Mark Rutland
  2018-06-19 16:14   ` Catalin Marinas
  19 siblings, 1 reply; 53+ messages in thread
From: Mark Rutland @ 2018-06-19 15:38 UTC (permalink / raw)
  To: linux-arm-kernel, catalin.marinas, will.deacon
  Cc: dave.martin, hch, james.morse, linux, linux-fsdevel, marc.zyngier, viro

On Mon, Jun 18, 2018 at 01:02:51PM +0100, Mark Rutland wrote:
> This series reworks arm64's syscall handling to minimize the propagation
> of user-controlled register values into speculated code paths. As with
> x86 [1], a wrapper is generated for each syscall, which extracts the
> argument from a struct pt_regs. During kernel entry from userspace,
> registers are zeroed.
> 
> The arm64 kernel code directly invokes some syscalls which the x86 code
> doesn't, so I've added ksys_* wrappers for these, following the x86
> example. The rest of the series is arm64-specific.
> 
> I've pushed the series out to my arm64/syscall-regs branch [2] on
> kernel.org.
> 
> Since v1 [3]:
> * Rebase atop of arm64 for-next/core (for SSBD conflicts)
> * Move ksys_personality logic into <linux/syscalls.h>
> * Move kcompat_sys_* wrappers to <linux/compat.h>
> * Fix scno bounds check to use unsigned comparison
> * Fix sve_user_reset() call in el0_svc_handler()
> * Add BUILD_BUG() to the !CONFIG_ARM64_SVE stubs
> * Accumulate acked-by / reviewed-by tags
> 
> Since v2 [4]:
> * Rebase to v4.18-rc1
> * Take upper 32 RES0 bits of SCTLR_ELx into account
> * Accumulate acks
> 
> Thanks,
> Mark.
> 
> [1] https://lkml.kernel.org/r/20180330093720.6780-1-linux@dominikbrodowski.net
> [2] git://git.kernel.org/pub/scm/linux/kernel/git/mark/linux.git
> [3] https://lkml.kernel.org/r/20180514094640.27569-1-mark.rutland@arm.com
> [4] https://lkml.kernel.org/r/20180601112441.37810-1-mark.rutland@arm.com
> 
> Mark Rutland (19):
>   arm64: consistently use unsigned long for thread flags
>   arm64: move SCTLR_EL{1,2} assertions to <asm/sysreg.h>
>   arm64: introduce sysreg_clear_set()
>   arm64: kill config_sctlr_el1()
>   arm64: kill change_cpacr()
>   arm64: move sve_user_{enable,disable} to <asm/fpsimd.h>
>   arm64: remove sigreturn wrappers
>   arm64: convert raw syscall invocation to C
>   arm64: convert syscall trace logic to C
>   arm64: convert native/compat syscall entry to C
>   arm64: don't reload GPRs after apply_ssbd
>   arm64: zero GPRs upon entry from EL0

I realised that along with these two, we also no longer need to reload
the GPRs for entry tracking, so I've added the following to my local
copy of the series.

Mark.

---->8----
>From b47791fe74fce8bb48696ab0cdda48a9bae0e397 Mon Sep 17 00:00:00 2001
From: Mark Rutland <mark.rutland@arm.com>
Date: Tue, 19 Jun 2018 12:49:54 +0100
Subject: [PATCH] arm64: don't restore GPRs when context tracking

Now that syscalls are invoked with pt_regs, we no longer need to ensure
that the argument regsiters are live in the entry assembly, and it's
fine to not restore them after context_tracking_user_exit() has
corrupted them.

Signed-off-by: Mark Rutland <mark.rutland@arm.com>
Cc: Catalin Marinas <catalin.marinas@arm.com>
Cc: Will Deacon <will.deacon@arm.com>
---
 arch/arm64/kernel/entry.S | 12 +-----------
 1 file changed, 1 insertion(+), 11 deletions(-)

diff --git a/arch/arm64/kernel/entry.S b/arch/arm64/kernel/entry.S
index 39440c2ee66d..6b7789d72064 100644
--- a/arch/arm64/kernel/entry.S
+++ b/arch/arm64/kernel/entry.S
@@ -41,19 +41,9 @@
  * Context tracking subsystem.  Used to instrument transitions
  * between user and kernel mode.
  */
-	.macro ct_user_exit, syscall = 0
+	.macro ct_user_exit
 #ifdef CONFIG_CONTEXT_TRACKING
 	bl	context_tracking_user_exit
-	.if \syscall == 1
-	/*
-	 * Save/restore needed during syscalls.  Restore syscall arguments from
-	 * the values already saved on stack during kernel_entry.
-	 */
-	ldp	x0, x1, [sp]
-	ldp	x2, x3, [sp, #S_X2]
-	ldp	x4, x5, [sp, #S_X4]
-	ldp	x6, x7, [sp, #S_X6]
-	.endif
 #endif
 	.endm
 
-- 
2.11.0

^ permalink raw reply related	[flat|nested] 53+ messages in thread

* Re: [PATCHv3 13/19] kernel: add ksys_personality()
  2018-06-18 12:03 ` [PATCHv3 13/19] kernel: add ksys_personality() Mark Rutland
@ 2018-06-19 15:45   ` Catalin Marinas
  2018-06-19 15:53     ` Mark Rutland
  0 siblings, 1 reply; 53+ messages in thread
From: Catalin Marinas @ 2018-06-19 15:45 UTC (permalink / raw)
  To: Mark Rutland
  Cc: linux-arm-kernel, will.deacon, marc.zyngier, linux, hch,
	james.morse, viro, linux-fsdevel, dave.martin

On Mon, Jun 18, 2018 at 01:03:04PM +0100, Mark Rutland wrote:
> diff --git a/include/linux/syscalls.h b/include/linux/syscalls.h
> index 73810808cdf2..14312d334345 100644
> --- a/include/linux/syscalls.h
> +++ b/include/linux/syscalls.h
> @@ -80,6 +80,7 @@ union bpf_attr;
>  #include <linux/unistd.h>
>  #include <linux/quota.h>
>  #include <linux/key.h>
> +#include <linux/personality.h>
>  #include <trace/syscall.h>
>  
>  #ifdef CONFIG_ARCH_HAS_SYSCALL_WRAPPER
> @@ -1277,4 +1278,14 @@ static inline long ksys_truncate(const char __user *pathname, loff_t length)
>  	return do_sys_truncate(pathname, length);
>  }
>  
> +static inline unsigned int ksys_personality(unsigned int personality)
> +{
> +	unsigned int old = current->personality;
> +
> +	if (personality != 0xffffffff)
> +		set_personality(personality);
> +
> +	return old;
> +}
> +
>  #endif

It looks like this is identical to sys_personality() in
kernel/exec_domain.c. Should you call ksys_personality() from there
directly (a few lines saved)?

-- 
Catalin

^ permalink raw reply	[flat|nested] 53+ messages in thread

* Re: [PATCHv3 15/19] arm64: remove in-kernel call to sys_personality()
  2018-06-18 12:03 ` [PATCHv3 15/19] arm64: remove in-kernel call to sys_personality() Mark Rutland
@ 2018-06-19 15:46   ` Catalin Marinas
  0 siblings, 0 replies; 53+ messages in thread
From: Catalin Marinas @ 2018-06-19 15:46 UTC (permalink / raw)
  To: Mark Rutland
  Cc: linux-arm-kernel, will.deacon, marc.zyngier, linux, hch,
	james.morse, viro, linux-fsdevel, dave.martin

On Mon, Jun 18, 2018 at 01:03:06PM +0100, Mark Rutland wrote:
> With pt_regs syscall wrappers, the calling convention for
> sys_personality() will change. Use ksys_personality(), which is
> functionally equivalent.
> 
> Signed-off-by: Mark Rutland <mark.rutland@arm.com>
> Cc: Catalin Marinas <catalin.marinas@arm.com>
> Cc: Will Deacon <will.deacon@arm.com>

Acked-by: Catalin Marinas <catalin.marinas@arm.com>

^ permalink raw reply	[flat|nested] 53+ messages in thread

* Re: [PATCHv3 16/19] arm64: use {COMPAT,}SYSCALL_DEFINE0 for sigreturn
  2018-06-18 12:03 ` [PATCHv3 16/19] arm64: use {COMPAT,}SYSCALL_DEFINE0 for sigreturn Mark Rutland
@ 2018-06-19 15:48   ` Catalin Marinas
  0 siblings, 0 replies; 53+ messages in thread
From: Catalin Marinas @ 2018-06-19 15:48 UTC (permalink / raw)
  To: Mark Rutland
  Cc: linux-arm-kernel, will.deacon, marc.zyngier, linux, hch,
	james.morse, viro, linux-fsdevel, dave.martin

On Mon, Jun 18, 2018 at 01:03:07PM +0100, Mark Rutland wrote:
> We don't currently annotate our various sigreturn functions as syscalls,
> as we need to do to use pt_regs syscall wrappers.
> 
> Let's mark them as real syscalls.
> 
> For compat_sys_sigreturn and compat_sys_rt_sigreturn, this changes the
> return type from int to long, matching the prototypes in sys32.c.
> 
> Signed-off-by: Mark Rutland <mark.rutland@arm.com>
> Reviewed-by: Dominik Brodowski <linux@dominikbrodowski.net>
> Cc: Catalin Marinas <catalin.marinas@arm.com>
> Cc: Will Deacon <will.deacon@arm.com>

Acked-by: Catalin Marinas <catalin.marinas@arm.com>

^ permalink raw reply	[flat|nested] 53+ messages in thread

* Re: [PATCHv3 17/19] arm64: use SYSCALL_DEFINE6() for mmap
  2018-06-18 12:03 ` [PATCHv3 17/19] arm64: use SYSCALL_DEFINE6() for mmap Mark Rutland
@ 2018-06-19 15:50   ` Catalin Marinas
  0 siblings, 0 replies; 53+ messages in thread
From: Catalin Marinas @ 2018-06-19 15:50 UTC (permalink / raw)
  To: Mark Rutland
  Cc: linux-arm-kernel, will.deacon, marc.zyngier, linux, hch,
	james.morse, viro, linux-fsdevel, dave.martin

On Mon, Jun 18, 2018 at 01:03:08PM +0100, Mark Rutland wrote:
> We don't currently annotate our mmap implementation as a syscall, as we
> need to do to use pt_regs syscall wrappers.
> 
> Let's mark it as a real syscall.
> 
> There should be no functional change as a result of this patch.
> 
> Signed-off-by: Mark Rutland <mark.rutland@arm.com>
> Reviewed-by: Dominik Brodowski <linux@dominikbrodowski.net>
> Cc: Catalin Marinas <catalin.marinas@arm.com>
> Cc: Will Deacon <will.deacon@arm.com>

Acked-by: Catalin Marinas <catalin.marinas@arm.com>

^ permalink raw reply	[flat|nested] 53+ messages in thread

* Re: [PATCHv3 18/19] arm64: convert compat wrappers to C
  2018-06-18 12:03 ` [PATCHv3 18/19] arm64: convert compat wrappers to C Mark Rutland
@ 2018-06-19 15:51   ` Catalin Marinas
  0 siblings, 0 replies; 53+ messages in thread
From: Catalin Marinas @ 2018-06-19 15:51 UTC (permalink / raw)
  To: Mark Rutland
  Cc: linux-arm-kernel, will.deacon, marc.zyngier, linux, hch,
	james.morse, viro, linux-fsdevel, dave.martin

On Mon, Jun 18, 2018 at 01:03:09PM +0100, Mark Rutland wrote:
> In preparation for converting to pt_regs syscall wrappers, convert our
> existing compat wrappers to C. This will allow the pt_regs wrappers to
> be automatically generated, and will allow for the compat register
> manipulation to be folded in with the pt_regs accesses.
> 
> To avoid confusion with the upcoming pt_regs wrappers and existing
> compat wrappers provided by core code, the C wrappers are renamed to
> compat_sys_aarch32_<syscall>.
> 
> With the assembly wrappers gone, we can get rid of entry32.S and the
> associated boilerplate.
> 
> Note that these must call the ksys_* syscall entry points, as the usual
> sys_* entry points will be modified to take a single pt_regs pointer
> argument.
> 
> Signed-off-by: Mark Rutland <mark.rutland@arm.com>
> Cc: Catalin Marinas <catalin.marinas@arm.com>
> Cc: Will Deacon <will.deacon@arm.com>

Acked-by: Catalin Marinas <catalin.marinas@arm.com>

^ permalink raw reply	[flat|nested] 53+ messages in thread

* Re: [PATCHv3 13/19] kernel: add ksys_personality()
  2018-06-19 15:45   ` Catalin Marinas
@ 2018-06-19 15:53     ` Mark Rutland
  0 siblings, 0 replies; 53+ messages in thread
From: Mark Rutland @ 2018-06-19 15:53 UTC (permalink / raw)
  To: Catalin Marinas
  Cc: linux-arm-kernel, will.deacon, marc.zyngier, linux, hch,
	james.morse, viro, linux-fsdevel, dave.martin

On Tue, Jun 19, 2018 at 04:45:41PM +0100, Catalin Marinas wrote:
> On Mon, Jun 18, 2018 at 01:03:04PM +0100, Mark Rutland wrote:
> > diff --git a/include/linux/syscalls.h b/include/linux/syscalls.h
> > index 73810808cdf2..14312d334345 100644
> > --- a/include/linux/syscalls.h
> > +++ b/include/linux/syscalls.h
> > @@ -80,6 +80,7 @@ union bpf_attr;
> >  #include <linux/unistd.h>
> >  #include <linux/quota.h>
> >  #include <linux/key.h>
> > +#include <linux/personality.h>
> >  #include <trace/syscall.h>
> >  
> >  #ifdef CONFIG_ARCH_HAS_SYSCALL_WRAPPER
> > @@ -1277,4 +1278,14 @@ static inline long ksys_truncate(const char __user *pathname, loff_t length)
> >  	return do_sys_truncate(pathname, length);
> >  }
> >  
> > +static inline unsigned int ksys_personality(unsigned int personality)
> > +{
> > +	unsigned int old = current->personality;
> > +
> > +	if (personality != 0xffffffff)
> > +		set_personality(personality);
> > +
> > +	return old;
> > +}
> > +
> >  #endif
> 
> It looks like this is identical to sys_personality() in
> kernel/exec_domain.c. Should you call ksys_personality() from there
> directly (a few lines saved)?

I had originally done so [1], but Christophe preferred that I open-code
the logic [2].

Thanks,
Mark.

[1] https://lkml.kernel.org/r/20180514094640.27569-13-mark.rutland@arm.com
[2] https://lkml.kernel.org/r/20180514120756.GA11638@infradead.org

^ permalink raw reply	[flat|nested] 53+ messages in thread

* Re: [PATCHv3 19/19] arm64: implement syscall wrappers
  2018-06-18 12:03 ` [PATCHv3 19/19] arm64: implement syscall wrappers Mark Rutland
@ 2018-06-19 16:13   ` Catalin Marinas
  0 siblings, 0 replies; 53+ messages in thread
From: Catalin Marinas @ 2018-06-19 16:13 UTC (permalink / raw)
  To: Mark Rutland
  Cc: linux-arm-kernel, will.deacon, marc.zyngier, linux, hch,
	james.morse, viro, linux-fsdevel, dave.martin

On Mon, Jun 18, 2018 at 01:03:10PM +0100, Mark Rutland wrote:
> To minimize the risk of userspace-controlled values being used under
> speculation, this patch adds pt_regs based syscall wrappers for arm64,
> which pass the minimum set of required userspace values to syscall
> implementations. For each syscall, a wrapper which takes a pt_regs
> argument is automatically generated, and this extracts the arguments
> before calling the "real" syscall implementation.
> 
> Each syscall has three functions generated:
> 
> * __do_<compat_>sys_<name> is the "real" syscall implementation, with
>   the expected prototype.
> 
> * __se_<compat_>sys_<name> is the sign-extension/narrowing wrapper,
>   inherited from common code. This takes a series of long parameters,
>   casting each to the requisite types required by the "real" syscall
>   implementation in __do_<compat_>sys_<name>.
> 
>   This wrapper *may* not be necessary on arm64 given the AAPCS rules on
>   unused register bits, but it seemed safer to keep the wrapper for now.
> 
> * __arm64_<compat_>_sys_<name> takes a struct pt_regs pointer, and
>   extracts *only* the relevant register values, passing these on to the
>   __se_<compat_>sys_<name> wrapper.
> 
> The syscall invocation code is updated to handle the calling convention
> required by __arm64_<compat_>_sys_<name>, and passes a single struct
> pt_regs pointer.
> 
> The compiler can fold the syscall implementation and its wrappers, such
> that the overhead of this approach is minimized.
> 
> Note that we play games with sys_ni_syscall(). It can't be defined with
> SYSCALL_DEFINE0() because we must avoid the possibility of error
> injection. Additionally, there are a couple of locations where we need
> to call it from C code, and we don't (currently) have a
> ksys_ni_syscall().  While it has no wrapper, passing in a redundant
> pt_regs pointer is benign per the AAPCS.
> 
> When ARCH_HAS_SYSCALL_WRAPPER is selected, no prototype is defines for
> sys_ni_syscall(). Since we need to treat it differently for in-kernel
> calls and the syscall tables, the prototype is defined as-required.
> 
> The wrappers are largely the same as their x86 counterparts, but
> simplified as we don't have a variety of compat calling conventions that
> require separate stubs. Unlike x86, we have some zero-argument compat
> syscalls, and must define COMPAT_SYSCALL_DEFINE0() to ensure that these
> are also given an __arm64_compat_sys_ prefix.
> 
> Signed-off-by: Mark Rutland <mark.rutland@arm.com>
> Reviewed-by: Dominik Brodowski <linux@dominikbrodowski.net>
> Cc: Catalin Marinas <catalin.marinas@arm.com>
> Cc: Will Deacon <will.deacon@arm.com>

Reviewed-by: Catalin Marinas <catalin.marinas@arm.com>

^ permalink raw reply	[flat|nested] 53+ messages in thread

* Re: [PATCHv3 00/19] arm64: invoke syscalls with pt_regs
  2018-06-19 15:38 ` [PATCHv3 00/19] arm64: invoke syscalls with pt_regs Mark Rutland
@ 2018-06-19 16:14   ` Catalin Marinas
  0 siblings, 0 replies; 53+ messages in thread
From: Catalin Marinas @ 2018-06-19 16:14 UTC (permalink / raw)
  To: Mark Rutland
  Cc: linux-arm-kernel, will.deacon, marc.zyngier, linux, hch,
	james.morse, viro, linux-fsdevel, dave.martin

On Tue, Jun 19, 2018 at 04:38:10PM +0100, Mark Rutland wrote:
> From b47791fe74fce8bb48696ab0cdda48a9bae0e397 Mon Sep 17 00:00:00 2001
> From: Mark Rutland <mark.rutland@arm.com>
> Date: Tue, 19 Jun 2018 12:49:54 +0100
> Subject: [PATCH] arm64: don't restore GPRs when context tracking
> 
> Now that syscalls are invoked with pt_regs, we no longer need to ensure
> that the argument regsiters are live in the entry assembly, and it's
> fine to not restore them after context_tracking_user_exit() has
> corrupted them.
> 
> Signed-off-by: Mark Rutland <mark.rutland@arm.com>
> Cc: Catalin Marinas <catalin.marinas@arm.com>
> Cc: Will Deacon <will.deacon@arm.com>

Acked-by: Catalin Marinas <catalin.marinas@arm.com>

^ permalink raw reply	[flat|nested] 53+ messages in thread

* Re: [PATCHv3 10/19] arm64: convert native/compat syscall entry to C
  2018-06-19 13:15     ` Mark Rutland
@ 2018-06-20  9:21       ` Dave Martin
  0 siblings, 0 replies; 53+ messages in thread
From: Dave Martin @ 2018-06-20  9:21 UTC (permalink / raw)
  To: Mark Rutland
  Cc: marc.zyngier, catalin.marinas, will.deacon, linux, hch,
	james.morse, viro, linux-fsdevel, linux-arm-kernel

On Tue, Jun 19, 2018 at 02:15:24PM +0100, Mark Rutland wrote:
> On Tue, Jun 19, 2018 at 01:18:17PM +0100, Dave Martin wrote:
> > On Mon, Jun 18, 2018 at 01:03:01PM +0100, Mark Rutland wrote:
> > > +static inline void sve_user_reset(void)
> > > +{
> > 
> > Can we call this "sve_user_discard" please?
> > 
> > "Reset" is a reasonable name for the concept, but the "discard"
> > terminology has been used elsewhere.
> 
> Sure; done.
> 
> > > +	if (!system_supports_sve())
> > > +		return;
> > > +
> > > +	/*
> > > +	 * task_fpsimd_load() won't be called to update CPACR_EL1 in
> > > +	 * ret_to_user unless TIF_FOREIGN_FPSTATE is still set, which only
> > > +	 * happens if a context switch or kernel_neon_begin() or context
> > > +	 * modification (sigreturn, ptrace) intervenes.
> > > +	 * So, ensure that CPACR_EL1 is already correct for the fast-path case.
> > > +	 */
> > 
> > This comment should go after clear_thead_flag(), since it describes not
> > the purpose of this function but the presence of sve_user_disable().
> > 
> > > +	clear_thread_flag(TIF_SVE);
> > > +	sve_user_disable();
> > > +}
> 
> Good point. I've moved the clear_thread_flag(TIF_SVE) above the comment
> (with a blank line before the comment).

Thanks -- with those changes:

Reviewed-by: Dave Martin <Dave.Martin@arm.com> (for the SVE parts)

Cheers
---Dave

^ permalink raw reply	[flat|nested] 53+ messages in thread

end of thread, other threads:[~2018-06-20  9:21 UTC | newest]

Thread overview: 53+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2018-06-18 12:02 [PATCHv3 00/19] arm64: invoke syscalls with pt_regs Mark Rutland
2018-06-18 12:02 ` [PATCHv3 01/19] arm64: consistently use unsigned long for thread flags Mark Rutland
2018-06-19 10:49   ` Catalin Marinas
2018-06-19 11:19     ` Mark Rutland
2018-06-18 12:02 ` [PATCHv3 02/19] arm64: move SCTLR_EL{1,2} assertions to <asm/sysreg.h> Mark Rutland
2018-06-19 11:02   ` [PATCHv3 02/19] arm64: move SCTLR_EL{1, 2} " Catalin Marinas
2018-06-19 11:48   ` [PATCHv3 02/19] arm64: move SCTLR_EL{1,2} " Mark Rutland
2018-06-18 12:02 ` [PATCHv3 03/19] arm64: introduce sysreg_clear_set() Mark Rutland
2018-06-19 11:44   ` Catalin Marinas
2018-06-19 11:47   ` Marc Zyngier
2018-06-18 12:02 ` [PATCHv3 04/19] arm64: kill config_sctlr_el1() Mark Rutland
2018-06-19 11:44   ` Catalin Marinas
2018-06-18 12:02 ` [PATCHv3 05/19] arm64: kill change_cpacr() Mark Rutland
2018-06-19 11:45   ` Catalin Marinas
2018-06-18 12:02 ` [PATCHv3 06/19] arm64: move sve_user_{enable,disable} to <asm/fpsimd.h> Mark Rutland
2018-06-19 12:00   ` [PATCHv3 06/19] arm64: move sve_user_{enable, disable} " Catalin Marinas
2018-06-19 12:19   ` Dave Martin
2018-06-18 12:02 ` [PATCHv3 07/19] arm64: remove sigreturn wrappers Mark Rutland
2018-06-19 12:47   ` Catalin Marinas
2018-06-18 12:02 ` [PATCHv3 08/19] arm64: convert raw syscall invocation to C Mark Rutland
2018-06-19 13:33   ` Catalin Marinas
2018-06-19 14:21   ` Catalin Marinas
2018-06-19 14:48     ` Mark Rutland
2018-06-19 14:55       ` Catalin Marinas
2018-06-19 14:58         ` Mark Rutland
2018-06-18 12:03 ` [PATCHv3 09/19] arm64: convert syscall trace logic " Mark Rutland
2018-06-19 14:32   ` Catalin Marinas
2018-06-19 15:14     ` Mark Rutland
2018-06-18 12:03 ` [PATCHv3 10/19] arm64: convert native/compat syscall entry " Mark Rutland
2018-06-19 12:18   ` Dave Martin
2018-06-19 13:15     ` Mark Rutland
2018-06-20  9:21       ` Dave Martin
2018-06-19 15:20   ` Catalin Marinas
2018-06-18 12:03 ` [PATCHv3 11/19] arm64: don't reload GPRs after apply_ssbd Mark Rutland
2018-06-19 15:23   ` Catalin Marinas
2018-06-18 12:03 ` [PATCHv3 12/19] arm64: zero GPRs upon entry from EL0 Mark Rutland
2018-06-19 15:24   ` Catalin Marinas
2018-06-18 12:03 ` [PATCHv3 13/19] kernel: add ksys_personality() Mark Rutland
2018-06-19 15:45   ` Catalin Marinas
2018-06-19 15:53     ` Mark Rutland
2018-06-18 12:03 ` [PATCHv3 14/19] kernel: add kcompat_sys_{f,}statfs64() Mark Rutland
2018-06-18 12:03 ` [PATCHv3 15/19] arm64: remove in-kernel call to sys_personality() Mark Rutland
2018-06-19 15:46   ` Catalin Marinas
2018-06-18 12:03 ` [PATCHv3 16/19] arm64: use {COMPAT,}SYSCALL_DEFINE0 for sigreturn Mark Rutland
2018-06-19 15:48   ` Catalin Marinas
2018-06-18 12:03 ` [PATCHv3 17/19] arm64: use SYSCALL_DEFINE6() for mmap Mark Rutland
2018-06-19 15:50   ` Catalin Marinas
2018-06-18 12:03 ` [PATCHv3 18/19] arm64: convert compat wrappers to C Mark Rutland
2018-06-19 15:51   ` Catalin Marinas
2018-06-18 12:03 ` [PATCHv3 19/19] arm64: implement syscall wrappers Mark Rutland
2018-06-19 16:13   ` Catalin Marinas
2018-06-19 15:38 ` [PATCHv3 00/19] arm64: invoke syscalls with pt_regs Mark Rutland
2018-06-19 16:14   ` Catalin Marinas

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).