Le 05/09/2020 à 19:43, 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>
---
  arch/powerpc/include/asm/interrupt.h   | 14 ++++++++
  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, 25 insertions(+), 45 deletions(-)

diff --git a/arch/powerpc/include/asm/interrupt.h 
b/arch/powerpc/include/asm/interrupt.h
index 3ae3d2f93b61..acfcc7d5779b 100644
--- a/arch/powerpc/include/asm/interrupt.h
+++ b/arch/powerpc/include/asm/interrupt.h
@@ -8,6 +8,16 @@
  #include <asm/ftrace.h>
  #include <asm/runlatch.h>
+static inline void nap_adjust_return(struct pt_regs *regs)
+{
+#ifdef CONFIG_PPC_970_NAP

Avoid #ifdef, you can use IS_ENABLED(CONFIG_PPC_970_NAP) in the 'if' below

+       if (test_thread_local_flags(_TLF_NAPPING)) {
+               clear_thread_local_flags(_TLF_NAPPING);
+               regs->nip = (unsigned long)power4_idle_nap_return;
+       }
+#endif
+}
+
  #ifdef CONFIG_PPC_BOOK3S_64
  static inline void interrupt_enter_prepare(struct pt_regs *regs)
  {
@@ -33,6 +43,8 @@ static inline void interrupt_async_enter_prepare(struct 
pt_regs *regs)
        if (cpu_has_feature(CPU_FTR_CTRL) &&
            !test_thread_local_flags(_TLF_RUNLATCH))
                __ppc64_runlatch_on();
+
+       nap_adjust_return(regs);
  }
#else /* CONFIG_PPC_BOOK3S_64 */
@@ -72,6 +84,8 @@ static inline void interrupt_nmi_enter_prepare(struct pt_regs 
*regs, struct inte
this_cpu_set_ftrace_enabled(0); + nap_adjust_return(regs);
+
        nmi_enter();
  }
diff --git a/arch/powerpc/include/asm/processor.h b/arch/powerpc/include/asm/processor.h
index ed0d633ab5aa..3da1dba91386 100644
--- a/arch/powerpc/include/asm/processor.h
+++ b/arch/powerpc/include/asm/processor.h
@@ -424,6 +424,7 @@ extern unsigned long isa300_idle_stop_mayloss(unsigned long 
psscr_val);
  extern unsigned long isa206_idle_insn_mayloss(unsigned long type);
  #ifdef CONFIG_PPC_970_NAP
  extern void power4_idle_nap(void);
+extern void power4_idle_nap_return(void);

Please please please, 'extern' keyword is pointless and deprecated for function prototypes. Don't add new ones.

Also, put it outside the #ifdef, so that you can use IS_ENABLED() instead of #ifdef when using it.

  #endif
extern unsigned long cpuidle_disable;
diff --git a/arch/powerpc/include/asm/thread_info.h 
b/arch/powerpc/include/asm/thread_info.h
index ca6c97025704..9b15f7edb0cb 100644
--- a/arch/powerpc/include/asm/thread_info.h
+++ b/arch/powerpc/include/asm/thread_info.h
@@ -156,6 +156,12 @@ void arch_setup_new_exec(void);
#ifndef __ASSEMBLY__ +static inline void clear_thread_local_flags(unsigned int flags)
+{
+       struct thread_info *ti = current_thread_info();
+       ti->local_flags &= ~flags;
+}
+
  static inline bool test_thread_local_flags(unsigned int flags)
  {
        struct thread_info *ti = current_thread_info();
diff --git a/arch/powerpc/kernel/exceptions-64s.S 
b/arch/powerpc/kernel/exceptions-64s.S
index 227bad3a586d..1db6b3438c88 100644
--- a/arch/powerpc/kernel/exceptions-64s.S
+++ b/arch/powerpc/kernel/exceptions-64s.S
@@ -692,25 +692,6 @@ END_FTR_SECTION_IFSET(CPU_FTR_CFAR)
        ld      r1,GPR1(r1)
  .endm
-/*
- * When the idle code in power4_idle puts the CPU into NAP mode,
- * it has to do so in a loop, and relies on the external interrupt
- * and decrementer interrupt entry code to get it out of the loop.
- * It sets the _TLF_NAPPING bit in current_thread_info()->local_flags
- * to signal that it is in the loop and needs help to get out.
- */
-#ifdef CONFIG_PPC_970_NAP
-#define FINISH_NAP                             \
-BEGIN_FTR_SECTION                              \
-       ld      r11, PACA_THREAD_INFO(r13);     \
-       ld      r9,TI_LOCAL_FLAGS(r11);         \
-       andi.   r10,r9,_TLF_NAPPING;            \
-       bnel    power4_fixup_nap;               \
-END_FTR_SECTION_IFSET(CPU_FTR_CAN_NAP)
-#else
-#define FINISH_NAP
-#endif
-
  /*
   * There are a few constraints to be concerned with.
   * - Real mode exceptions code/data must be located at their physical 
location.
@@ -1250,7 +1231,6 @@ EXC_COMMON_BEGIN(machine_check_common)
         */
        GEN_COMMON machine_check
- FINISH_NAP
        /* Enable MSR_RI when finished with PACA_EXMC */
        li      r10,MSR_RI
        mtmsrd  r10,1
@@ -1572,7 +1552,6 @@ EXC_VIRT_BEGIN(hardware_interrupt, 0x4500, 0x100)
  EXC_VIRT_END(hardware_interrupt, 0x4500, 0x100)
  EXC_COMMON_BEGIN(hardware_interrupt_common)
        GEN_COMMON hardware_interrupt
-       FINISH_NAP
        addi    r3,r1,STACK_FRAME_OVERHEAD
        bl      do_IRQ
        b       interrupt_return
@@ -1757,7 +1736,6 @@ EXC_VIRT_BEGIN(decrementer, 0x4900, 0x80)
  EXC_VIRT_END(decrementer, 0x4900, 0x80)
  EXC_COMMON_BEGIN(decrementer_common)
        GEN_COMMON decrementer
-       FINISH_NAP
        addi    r3,r1,STACK_FRAME_OVERHEAD
        bl      timer_interrupt
        b       interrupt_return
@@ -1842,7 +1820,6 @@ EXC_VIRT_BEGIN(doorbell_super, 0x4a00, 0x100)
  EXC_VIRT_END(doorbell_super, 0x4a00, 0x100)
  EXC_COMMON_BEGIN(doorbell_super_common)
        GEN_COMMON doorbell_super
-       FINISH_NAP
        addi    r3,r1,STACK_FRAME_OVERHEAD
  #ifdef CONFIG_PPC_DOORBELL
        bl      doorbell_exception
@@ -2196,7 +2173,6 @@ EXC_COMMON_BEGIN(hmi_exception_early_common)
EXC_COMMON_BEGIN(hmi_exception_common)
        GEN_COMMON hmi_exception
-       FINISH_NAP
        addi    r3,r1,STACK_FRAME_OVERHEAD
        bl      handle_hmi_exception
        b       interrupt_return
@@ -2225,7 +2201,6 @@ EXC_VIRT_BEGIN(h_doorbell, 0x4e80, 0x20)
  EXC_VIRT_END(h_doorbell, 0x4e80, 0x20)
  EXC_COMMON_BEGIN(h_doorbell_common)
        GEN_COMMON h_doorbell
-       FINISH_NAP
        addi    r3,r1,STACK_FRAME_OVERHEAD
  #ifdef CONFIG_PPC_DOORBELL
        bl      doorbell_exception
@@ -2258,7 +2233,6 @@ EXC_VIRT_BEGIN(h_virt_irq, 0x4ea0, 0x20)
  EXC_VIRT_END(h_virt_irq, 0x4ea0, 0x20)
  EXC_COMMON_BEGIN(h_virt_irq_common)
        GEN_COMMON h_virt_irq
-       FINISH_NAP
        addi    r3,r1,STACK_FRAME_OVERHEAD
        bl      do_IRQ
        b       interrupt_return
@@ -2304,7 +2278,6 @@ EXC_VIRT_BEGIN(performance_monitor, 0x4f00, 0x20)
  EXC_VIRT_END(performance_monitor, 0x4f00, 0x20)
  EXC_COMMON_BEGIN(performance_monitor_common)
        GEN_COMMON performance_monitor
-       FINISH_NAP
        addi    r3,r1,STACK_FRAME_OVERHEAD
        bl      performance_monitor_exception
        b       interrupt_return
@@ -3032,24 +3005,6 @@ USE_FIXED_SECTION(virt_trampolines)
  __end_interrupts:
  DEFINE_FIXED_SYMBOL(__end_interrupts)
-#ifdef CONFIG_PPC_970_NAP
-       /*
-        * Called by exception entry code if _TLF_NAPPING was set, this clears
-        * the NAPPING flag, and redirects the exception exit to
-        * power4_fixup_nap_return.
-        */
-       .globl power4_fixup_nap
-EXC_COMMON_BEGIN(power4_fixup_nap)
-       andc    r9,r9,r10
-       std     r9,TI_LOCAL_FLAGS(r11)
-       LOAD_REG_ADDR(r10, power4_idle_nap_return)
-       std     r10,_NIP(r1)
-       blr
-
-power4_idle_nap_return:
-       blr
-#endif
-
  CLOSE_FIXED_SECTION(real_vectors);
  CLOSE_FIXED_SECTION(real_trampolines);
  CLOSE_FIXED_SECTION(virt_vectors);
diff --git a/arch/powerpc/kernel/idle_book3s.S 
b/arch/powerpc/kernel/idle_book3s.S
index 22f249b6f58d..27d2e6a72ec9 100644
--- a/arch/powerpc/kernel/idle_book3s.S
+++ b/arch/powerpc/kernel/idle_book3s.S
@@ -201,4 +201,8 @@ _GLOBAL(power4_idle_nap)
        mtmsrd  r7
        isync
        b       1b
+
+       .globl power4_idle_nap_return
+power4_idle_nap_return:
+       blr

Can't this be written in C somewhere ?

  #endif


Christophe

Reply via email to