linuxppc-dev.lists.ozlabs.org archive mirror
 help / color / mirror / Atom feed
From: Nicholas Piggin <npiggin@gmail.com>
To: linuxppc-dev@lists.ozlabs.org
Cc: Nicholas Piggin <npiggin@gmail.com>
Subject: [PATCH v4 14/21] powerpc/64s: move context tracking exit to interrupt exit path
Date: Sat,  2 Jan 2021 22:25:01 +1000	[thread overview]
Message-ID: <20210102122508.1950592-15-npiggin@gmail.com> (raw)
In-Reply-To: <20210102122508.1950592-1-npiggin@gmail.com>

The interrupt handler wrapper functions are not the ideal place to
maintain context tracking because after they return, the low level exit
code must then determine if there are interrupts to replay, or if the
task should be preempted, etc. Those paths (e.g., schedule_user) include
their own exception_enter/exit pairs to fix this up but it's a bit hacky
(see schedule_user() comments).

Ideally context tracking will go to user mode only when there are no
more interrupts or context switches or other exit processing work to
handle.

64e can not do this because it does not use the C interrupt exit code.

Signed-off-by: Nicholas Piggin <npiggin@gmail.com>
---
 arch/powerpc/include/asm/interrupt.h | 34 +++++++++++++++++++++++++---
 arch/powerpc/kernel/syscall_64.c     |  9 ++++++++
 2 files changed, 40 insertions(+), 3 deletions(-)

diff --git a/arch/powerpc/include/asm/interrupt.h b/arch/powerpc/include/asm/interrupt.h
index bee393c72fe5..34d7cca2cb2e 100644
--- a/arch/powerpc/include/asm/interrupt.h
+++ b/arch/powerpc/include/asm/interrupt.h
@@ -7,16 +7,30 @@
 #include <asm/ftrace.h>
 
 struct interrupt_state {
-#ifdef CONFIG_PPC64
+#ifdef CONFIG_PPC_BOOK3E_64
 	enum ctx_state ctx_state;
 #endif
 };
 
 static inline void interrupt_enter_prepare(struct pt_regs *regs, struct interrupt_state *state)
 {
-#ifdef CONFIG_PPC64
+#ifdef CONFIG_PPC_BOOK3E_64
 	state->ctx_state = exception_enter();
 #endif
+
+#ifdef CONFIG_PPC_BOOK3S_64
+	if (user_mode(regs)) {
+		CT_WARN_ON(ct_state() != CONTEXT_USER);
+		user_exit_irqoff();
+	} else {
+		/*
+		 * CT_WARN_ON comes here via program_check_exception,
+		 * so avoid recursion.
+		 */
+		if (TRAP(regs) != 0x700)
+			CT_WARN_ON(ct_state() != CONTEXT_KERNEL);
+	}
+#endif
 }
 
 /*
@@ -35,9 +49,23 @@ static inline void interrupt_enter_prepare(struct pt_regs *regs, struct interrup
  */
 static inline void interrupt_exit_prepare(struct pt_regs *regs, struct interrupt_state *state)
 {
-#ifdef CONFIG_PPC64
+#ifdef CONFIG_PPC_BOOK3E_64
 	exception_exit(state->ctx_state);
 #endif
+
+	/*
+	 * Book3S exits to user via interrupt_exit_user_prepare(), which does
+	 * context tracking, which is a cleaner way to handle PREEMPT=y
+	 * and avoid context entry/exit in e.g., preempt_schedule_irq()),
+	 * which is likely to be where the core code wants to end up.
+	 *
+	 * The above comment explains why we can't do the
+	 *
+	 *     if (user_mode(regs))
+	 *         user_exit_irqoff();
+	 *
+	 * sequence here.
+	 */
 }
 
 static inline void interrupt_async_enter_prepare(struct pt_regs *regs, struct interrupt_state *state)
diff --git a/arch/powerpc/kernel/syscall_64.c b/arch/powerpc/kernel/syscall_64.c
index d7d256a7a41f..42f0ad4b2fbb 100644
--- a/arch/powerpc/kernel/syscall_64.c
+++ b/arch/powerpc/kernel/syscall_64.c
@@ -305,6 +305,7 @@ notrace unsigned long interrupt_exit_user_prepare(struct pt_regs *regs, unsigned
 	BUG_ON(!(regs->msr & MSR_PR));
 	BUG_ON(!FULL_REGS(regs));
 	BUG_ON(regs->softe != IRQS_ENABLED);
+	CT_WARN_ON(ct_state() == CONTEXT_USER);
 
 	/*
 	 * We don't need to restore AMR on the way back to userspace for KUAP.
@@ -347,7 +348,9 @@ notrace unsigned long interrupt_exit_user_prepare(struct pt_regs *regs, unsigned
 		}
 	}
 
+	user_enter_irqoff();
 	if (unlikely(!prep_irq_for_enabled_exit(true))) {
+		user_exit_irqoff();
 		local_irq_enable();
 		local_irq_disable();
 		goto again;
@@ -392,6 +395,12 @@ notrace unsigned long interrupt_exit_kernel_prepare(struct pt_regs *regs, unsign
 		unrecoverable_exception(regs);
 	BUG_ON(regs->msr & MSR_PR);
 	BUG_ON(!FULL_REGS(regs));
+	/*
+	 * CT_WARN_ON comes here via program_check_exception,
+	 * so avoid recursion.
+	 */
+	if (TRAP(regs) != 0x700)
+		CT_WARN_ON(ct_state() == CONTEXT_USER);
 
 	amr = kuap_get_and_check_amr();
 
-- 
2.23.0


  parent reply	other threads:[~2021-01-02 13:09 UTC|newest]

Thread overview: 24+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2021-01-02 12:24 [PATCH v4 00/21] powerpc: interrupt wrappers Nicholas Piggin
2021-01-02 12:24 ` [PATCH v4 01/21] powerpc/32s: Do DABR match out of handle_page_fault() Nicholas Piggin
2021-01-02 12:24 ` [PATCH v4 02/21] powerpc/64s: move the last of the page fault handling logic to C Nicholas Piggin
2021-01-02 17:56   ` Christophe Leroy
2021-01-03  9:17     ` Nicholas Piggin
2021-01-02 12:24 ` [PATCH v4 03/21] powerpc: remove arguments from fault handler functions Nicholas Piggin
2021-01-02 12:24 ` [PATCH v4 04/21] powerpc: bad_page_fault, do_break get registers from regs Nicholas Piggin
2021-01-02 12:24 ` [PATCH v4 05/21] powerpc/perf: move perf irq/nmi handling details into traps.c Nicholas Piggin
2021-01-02 12:24 ` [PATCH v4 06/21] powerpc: interrupt handler wrapper functions Nicholas Piggin
2021-01-02 12:24 ` [PATCH v4 07/21] powerpc: add interrupt wrapper entry / exit stub functions Nicholas Piggin
2021-01-02 12:24 ` [PATCH v4 08/21] powerpc: add interrupt_cond_local_irq_enable helper Nicholas Piggin
2021-01-02 12:24 ` [PATCH v4 09/21] powerpc/64: context tracking remove _TIF_NOHZ Nicholas Piggin
2021-01-02 12:24 ` [PATCH v4 10/21] powerpc/64s/hash: improve context tracking of hash faults Nicholas Piggin
2021-01-02 12:24 ` [PATCH v4 11/21] powerpc/64: context tracking move to interrupt wrappers Nicholas Piggin
2021-01-02 12:24 ` [PATCH v4 12/21] powerpc/64: add context tracking to asynchronous interrupts Nicholas Piggin
2021-01-02 12:25 ` [PATCH v4 13/21] powerpc: handle irq_enter/irq_exit in interrupt handler wrappers Nicholas Piggin
2021-01-02 12:25 ` Nicholas Piggin [this message]
2021-01-02 12:25 ` [PATCH v4 15/21] powerpc/64s: reconcile interrupts in C Nicholas Piggin
2021-01-02 12:25 ` [PATCH v4 16/21] powerpc/64: move account_stolen_time into its own function Nicholas Piggin
2021-01-02 12:25 ` [PATCH v4 17/21] powerpc/64: entry cpu time accounting in C Nicholas Piggin
2021-01-02 12:25 ` [PATCH v4 18/21] powerpc: move NMI entry/exit code into wrapper Nicholas Piggin
2021-01-02 12:25 ` [PATCH v4 19/21] powerpc/64s: move NMI soft-mask handling to C Nicholas Piggin
2021-01-02 12:25 ` [PATCH v4 20/21] powerpc/64s: runlatch interrupt handling in C Nicholas Piggin
2021-01-02 12:25 ` [PATCH v4 21/21] powerpc/64s: power4 nap fixup " Nicholas Piggin

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=20210102122508.1950592-15-npiggin@gmail.com \
    --to=npiggin@gmail.com \
    --cc=linuxppc-dev@lists.ozlabs.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 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).