Le 12/03/2021 à 02:20, Nicholas Piggin a écrit :
There is no need for this to be in asm, use the new intrrupt entry wrapper.

Signed-off-by: Nicholas Piggin <npig...@gmail.com>
---
Hopefully this works on a real G5 now, but I couldn't reproduce the
problem with QEMU.

Thanks,
Nick

  arch/powerpc/include/asm/interrupt.h   | 19 +++++++++++
  arch/powerpc/include/asm/processor.h   |  1 +
  arch/powerpc/include/asm/thread_info.h |  6 ++++
  arch/powerpc/kernel/exceptions-64s.S   | 45 --------------------------
  arch/powerpc/kernel/idle_book3s.S      |  4 +++
  5 files changed, 30 insertions(+), 45 deletions(-)

diff --git a/arch/powerpc/include/asm/interrupt.h 
b/arch/powerpc/include/asm/interrupt.h
index aedfba29e43a..ef015d3b5e39 100644
--- a/arch/powerpc/include/asm/interrupt.h
+++ b/arch/powerpc/include/asm/interrupt.h
@@ -9,6 +9,17 @@
  #include <asm/kprobes.h>
  #include <asm/runlatch.h>
+static inline void nap_adjust_return(struct pt_regs *regs)
+{
+#ifdef CONFIG_PPC_970_NAP
+       if (unlikely(test_thread_local_flags(_TLF_NAPPING))) {
+               /* Can avoid a test-and-clear because NMIs do not call this */
+               clear_thread_local_flags(_TLF_NAPPING);
+               regs->nip = (unsigned long)power4_idle_nap_return;

Why don't you do regs->nip = regs->link like PPC32 instead of going via an intermediate symbol that does nothing else than branching to LR ?

+       }
+#endif
+}
+
  struct interrupt_state {
  #ifdef CONFIG_PPC_BOOK3E_64
        enum ctx_state ctx_state;
@@ -111,6 +122,9 @@ static inline void interrupt_async_exit_prepare(struct 
pt_regs *regs, struct int
  {
        irq_exit();
        interrupt_exit_prepare(regs, state);
+
+       /* Adjust at exit so the main handler sees the true NIA */
+       nap_adjust_return(regs);
  }
struct interrupt_nmi_state {
@@ -164,6 +178,11 @@ static inline void interrupt_nmi_exit_prepare(struct 
pt_regs *regs, struct inter
                        radix_enabled() || (mfmsr() & MSR_DR))
                nmi_exit();
+ /*
+        * nmi does not call nap_adjust_return because nmi should not create
+        * new work to do (must use irq_work for that).
+        */
+
  #ifdef CONFIG_PPC64
        if (TRAP(regs) != 0x900 && TRAP(regs) != 0xf00 && TRAP(regs) != 0x260)
                this_cpu_set_ftrace_enabled(state->ftrace_enabled);

...

diff --git a/arch/powerpc/kernel/idle_book3s.S 
b/arch/powerpc/kernel/idle_book3s.S
index f9e6d83e6720..abb719b21cae 100644
--- a/arch/powerpc/kernel/idle_book3s.S
+++ b/arch/powerpc/kernel/idle_book3s.S
@@ -209,4 +209,8 @@ _GLOBAL(power4_idle_nap)
        mtmsrd  r7
        isync
        b       1b
+
+       .globl power4_idle_nap_return
+power4_idle_nap_return:
+       blr
  #endif

Reply via email to