All of lore.kernel.org
 help / color / mirror / Atom feed
From: Thomas Gleixner <tglx@linutronix.de>
To: LKML <linux-kernel@vger.kernel.org>
Cc: x86@kernel.org, Peter Zijlstra <peterz@infradead.org>,
	Andy Lutomirski <luto@kernel.org>,
	Catalin Marinas <catalin.marinas@arm.com>,
	Will Deacon <will@kernel.org>,
	Mark Rutland <mark.rutland@arm.com>,
	Marc Zyngier <maz@kernel.org>,
	Paolo Bonzini <pbonzini@redhat.com>,
	kvm@vger.kernel.org, linux-arch@vger.kernel.org
Subject: [RFC patch 09/15] entry: Provide generic exit to usermode functionality
Date: Thu, 19 Sep 2019 17:03:23 +0200	[thread overview]
Message-ID: <20190919150809.340471236@linutronix.de> (raw)
In-Reply-To: 20190919150314.054351477@linutronix.de

Provide a generic facility to handle the exit to usermode work. That's
aimed to replace the pointlessly different copies in each architecture.

Signed-off-by: Thomas Gleixner <tglx@linutronix.de>
---
 include/linux/entry-common.h |  105 +++++++++++++++++++++++++++++++++++++++++++
 kernel/entry/common.c        |   88 ++++++++++++++++++++++++++++++++++++
 2 files changed, 193 insertions(+)

--- a/include/linux/entry-common.h
+++ b/include/linux/entry-common.h
@@ -34,6 +34,30 @@
 # define _TIF_AUDIT			(0)
 #endif
 
+#ifndef _TIF_UPROBE
+# define _TIF_UPROBE			(0)
+#endif
+
+#ifndef _TIF_PATCH_PENDING
+# define _TIF_PATCH_PENDING		(0)
+#endif
+
+#ifndef _TIF_NOTIFY_RESUME
+# define _TIF_NOTIFY_RESUME		(0)
+#endif
+
+/*
+ * TIF flags handled in exit_to_usermode()
+ */
+#ifndef ARCH_EXIT_TO_USERMODE_WORK
+# define ARCH_EXIT_TO_USERMODE_WORK	(0)
+#endif
+
+#define EXIT_TO_USERMODE_WORK						\
+	(_TIF_SIGPENDING | _TIF_NOTIFY_RESUME | _TIF_UPROBE |		\
+	 _TIF_NEED_RESCHED | _TIF_PATCH_PENDING |			\
+	 ARCH_EXIT_TO_USERMODE_WORK)
+
 /*
  * TIF flags handled in syscall_enter_from_usermode()
  */
@@ -58,6 +82,87 @@
 	 _TIF_SYSCALL_TRACEPOINT | ARCH_SYSCALL_EXIT_WORK)
 
 /**
+ * local_irq_enable_exit_to_user - Exit to user variant of local_irq_enable()
+ * @ti_work:	Cached TIF flags gathered with interrupts disabled
+ *
+ * Defaults to local_irq_enable(). Can be supplied by architecture specific
+ * code.
+ */
+static inline void local_irq_enable_exit_to_user(unsigned long ti_work);
+
+#ifndef local_irq_enable_exit_to_user
+static inline void local_irq_enable_exit_to_user(unsigned long ti_work)
+{
+	local_irq_enable();
+}
+#endif
+
+/**
+ * local_irq_disable_exit_to_user - Exit to user variant of local_irq_disable()
+ *
+ * Defaults to local_irq_disable(). Can be supplied by architecture specific
+ * code.
+ */
+static inline void local_irq_disable_exit_to_user(void);
+
+#ifndef local_irq_disable_exit_to_user
+static inline void local_irq_disable_exit_to_user(void)
+{
+	local_irq_disable();
+}
+#endif
+
+/**
+ * arch_exit_to_usermode_work - Architecture specific TIF work for
+ *				exit to user mode.
+ * @regs:	Pointer to currents pt_regs
+ * @ti_work:	Cached TIF flags gathered with interrupts disabled
+ *
+ * Invoked from exit_to_usermode() with interrupt disabled
+ *
+ * Defaults to NOOP. Can be supplied by architecture specific code.
+ */
+static inline void arch_exit_to_usermode_work(struct pt_regs *regs,
+					      unsigned long ti_work);
+
+#ifndef arch_exit_to_usermode_work
+static inline void arch_exit_to_usermode_work(struct pt_regs *regs,
+					      unsigned long ti_work)
+{
+}
+#endif
+
+/**
+ * arch_exit_to_usermode - Architecture specific preparation for
+ *			   exit to user mode.
+ * @regs:	Pointer to currents pt_regs
+ * @ti_work:	Cached TIF flags gathered with interrupts disabled
+ *
+ * Invoked from exit_to_usermode() with interrupt disabled as the last
+ * function before return.
+ */
+static inline void arch_exit_to_usermode(struct pt_regs *regs,
+					 unsigned long ti_work);
+
+#ifndef arch_exit_to_usermode
+static inline void arch_exit_to_usermode(struct pt_regs *regs,
+					 unsigned long ti_work)
+{
+}
+#endif
+
+/* Common exit to usermode function to handle TIF work */
+asmlinkage __visible void exit_to_usermode(struct pt_regs *regs);
+
+/**
+ * arch_do_signal -  Architecture specific signal delivery function
+ * @regs:	Pointer to currents pt_regs
+ *
+ * Invoked from exit_to_usermode()
+ */
+void arch_do_signal(struct pt_regs *regs);
+
+/**
  * arch_syscall_enter_tracehook - Wrapper around tracehook_report_syscall_entry()
  *
  * Defaults to tracehook_report_syscall_entry(). Can be replaced by
--- a/kernel/entry/common.c
+++ b/kernel/entry/common.c
@@ -2,10 +2,90 @@
 
 #include <linux/context_tracking.h>
 #include <linux/entry-common.h>
+#include <linux/livepatch.h>
+#include <linux/uprobes.h>
 
 #define CREATE_TRACE_POINTS
 #include <trace/events/syscalls.h>
 
+static unsigned long core_exit_to_usermode_work(struct pt_regs *regs,
+						unsigned long ti_work)
+{
+	/*
+	 * Before returning to user space ensure that all pending work
+	 * items have been completed.
+	 */
+	while (ti_work & EXIT_TO_USERMODE_WORK) {
+
+		local_irq_enable_exit_to_user(ti_work);
+
+		if (ti_work & _TIF_NEED_RESCHED)
+			schedule();
+
+		if (ti_work & _TIF_UPROBE)
+			uprobe_notify_resume(regs);
+
+		if (ti_work & _TIF_PATCH_PENDING)
+			klp_update_patch_state(current);
+
+		if (ti_work & _TIF_SIGPENDING)
+			arch_do_signal(regs);
+
+		if (ti_work & _TIF_NOTIFY_RESUME) {
+			clear_thread_flag(TIF_NOTIFY_RESUME);
+			tracehook_notify_resume(regs);
+			rseq_handle_notify_resume(NULL, regs);
+		}
+
+		/* Architecture specific TIF work */
+		arch_exit_to_usermode_work(regs, ti_work);
+
+		/*
+		 * Disable interrupts and reevaluate the work flags as they
+		 * might have changed while interrupts and preemption was
+		 * enabled above.
+		 */
+		local_irq_disable_exit_to_user();
+		ti_work = READ_ONCE(current_thread_info()->flags);
+	}
+	/*
+	 * Was checked in exit_to_usermode_work() already, but the above
+	 * loop might have wreckaged it.
+	 */
+	addr_limit_user_check();
+	return ti_work;
+}
+
+static void do_exit_to_usermode(struct pt_regs *regs)
+{
+	unsigned long ti_work = READ_ONCE(current_thread_info()->flags);
+
+	lockdep_sys_exit();
+
+	addr_limit_user_check();
+
+	if (unlikely(ti_work & EXIT_TO_USERMODE_WORK))
+		ti_work = core_exit_to_usermode_work(regs, ti_work);
+
+	arch_exit_to_usermode(regs, ti_work);
+	/* Return to userspace right after this which turns on interrupts */
+	trace_hardirqs_on();
+}
+
+/**
+ * exit_to_usermode - Check and handle pending work which needs to be
+ *		      handled before returning to user mode
+ * @regs:	Pointer to currents pt_regs
+ *
+ * Called and returns with interrupts disabled
+ */
+asmlinkage __visible void exit_to_usermode(struct pt_regs *regs)
+{
+	trace_hardirqs_off();
+	lockdep_assert_irqs_disabled();
+	do_exit_to_usermode(regs);
+}
+
 long core_syscall_enter_from_usermode(struct pt_regs *regs, long syscall)
 {
 	unsigned long ti_work = READ_ONCE(current_thread_info()->flags);
@@ -85,4 +165,12 @@ void syscall_exit_to_usermode(struct pt_
 	ti_work = READ_ONCE(current_thread_info()->flags);
 	if (unlikely(ti_work & SYSCALL_EXIT_WORK))
 		syscall_exit_work(regs, retval, ti_work);
+
+#ifdef ARCH_EXIT_TO_USER_FROM_SYSCALL_EXIT
+	/*
+	 * Disable interrupts and handle the regular exit to user mode work
+	 */
+	local_irq_disable_exit_to_user();
+	do_exit_to_usermode(regs);
+#endif
 }



  parent reply	other threads:[~2019-09-19 15:10 UTC|newest]

Thread overview: 43+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2019-09-19 15:03 [RFC patch 00/15] entry: Provide generic implementation for host and guest entry/exit work Thomas Gleixner
2019-09-19 15:03 ` [RFC patch 01/15] entry: Provide generic syscall entry functionality Thomas Gleixner
2019-09-20 23:38   ` Andy Lutomirski
2019-10-20 11:49     ` Thomas Gleixner
2019-09-23  9:05   ` Mike Rapoport
2019-09-19 15:03 ` [RFC patch 02/15] x86/entry: Remove _TIF_NOHZ from _TIF_WORK_SYSCALL_ENTRY Thomas Gleixner
2019-09-20 23:39   ` Andy Lutomirski
2019-09-23 20:43     ` Thomas Gleixner
2019-09-19 15:03 ` [RFC patch 03/15] x86/entry: Use generic syscall entry function Thomas Gleixner
2019-09-20 23:41   ` Andy Lutomirski
2019-09-23  8:31     ` Peter Zijlstra
2019-09-23  8:40       ` Thomas Gleixner
2019-09-19 15:03 ` [RFC patch 04/15] arm64/entry: " Thomas Gleixner
2019-09-20 12:21   ` Catalin Marinas
2019-09-19 15:03 ` [RFC patch 05/15] entry: Provide generic syscall exit function Thomas Gleixner
2019-09-19 15:03 ` [RFC patch 06/15] x86/entry: Use generic syscall exit functionality Thomas Gleixner
2019-09-19 15:03 ` [RFC patch 07/15] arm64/syscall: Remove obscure flag check Thomas Gleixner
2019-09-20 14:29   ` Catalin Marinas
2019-09-19 15:03 ` [RFC patch 08/15] arm64/syscall: Use generic syscall exit functionality Thomas Gleixner
2019-09-19 15:03 ` Thomas Gleixner [this message]
2019-09-23  8:30   ` [RFC patch 09/15] entry: Provide generic exit to usermode functionality Peter Zijlstra
2019-09-19 15:03 ` [RFC patch 10/15] x86/entry: Move irq tracing to C code Thomas Gleixner
2019-09-23  8:47   ` Peter Zijlstra
2019-09-23 10:27     ` Thomas Gleixner
2019-09-23 11:49       ` Peter Zijlstra
2019-09-23 11:55         ` Peter Zijlstra
2019-09-23 12:10           ` Peter Zijlstra
2019-09-23 17:24             ` Andy Lutomirski
2019-09-26  2:59   ` Josh Poimboeuf
2019-09-19 15:03 ` [RFC patch 11/15] x86/entry: Use generic exit to usermode Thomas Gleixner
2019-09-19 15:03 ` [RFC patch 12/15] arm64/entry: " Thomas Gleixner
2019-09-19 15:03 ` [RFC patch 13/15] arm64/entry: Move FPU restore out of exit_to_usermode() loop Thomas Gleixner
2019-09-19 15:03 ` [RFC patch 14/15] workpending: Provide infrastructure for work before entering a guest Thomas Gleixner
2019-09-19 15:40   ` Paolo Bonzini
2019-09-20 11:48     ` Thomas Gleixner
2019-09-23 18:17   ` Andy Lutomirski
2019-09-26 11:35   ` Miroslav Benes
2019-09-19 15:03 ` [RFC patch 15/15] x86/kvm: Use GENERIC_EXIT_WORKPENDING Thomas Gleixner
2019-09-19 15:40   ` Paolo Bonzini
2019-09-20 15:12 ` [RFC patch 00/15] entry: Provide generic implementation for host and guest entry/exit work Mark Rutland
2019-09-23 20:50   ` Thomas Gleixner
2019-09-23 18:18 ` Andy Lutomirski
2019-09-24  6:50 ` Christian Borntraeger

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20190919150809.340471236@linutronix.de \
    --to=tglx@linutronix.de \
    --cc=catalin.marinas@arm.com \
    --cc=kvm@vger.kernel.org \
    --cc=linux-arch@vger.kernel.org \
    --cc=linux-kernel@vger.kernel.org \
    --cc=luto@kernel.org \
    --cc=mark.rutland@arm.com \
    --cc=maz@kernel.org \
    --cc=pbonzini@redhat.com \
    --cc=peterz@infradead.org \
    --cc=will@kernel.org \
    --cc=x86@kernel.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.