[PATCH] powerpc/64s: power4 nap fixup in C

Subsystems: linux for powerpc (32-bit and 64-bit), the rest

STALE1960d

8 messages, 5 authors, 2021-04-19 · open the first message on its own page

[PATCH] powerpc/64s: power4 nap fixup in C

From: Nicholas Piggin <npiggin@gmail.com>
Date: 2021-03-12 01:21:35

There is no need for this to be in asm, use the new intrrupt entry wrapper.

Signed-off-by: Nicholas Piggin <npiggin@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;
+	}
+#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/include/asm/processor.h b/arch/powerpc/include/asm/processor.h
index 8acc3590c971..eedc3c775141 100644
--- a/arch/powerpc/include/asm/processor.h
+++ b/arch/powerpc/include/asm/processor.h
@@ -393,6 +393,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);
+void power4_idle_nap_return(void);
 #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 386d576673a1..bf137151100b 100644
--- a/arch/powerpc/include/asm/thread_info.h
+++ b/arch/powerpc/include/asm/thread_info.h
@@ -152,6 +152,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 60d3051a8bc8..ea7a443488d2 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.
@@ -1248,7 +1229,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
@@ -1571,7 +1551,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
@@ -1801,7 +1780,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
@@ -1886,7 +1864,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
@@ -2237,7 +2214,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
@@ -2266,7 +2242,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
@@ -2299,7 +2274,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
@@ -2345,7 +2319,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
@@ -3096,24 +3069,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 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
-- 
2.23.0

Re: [PATCH] powerpc/64s: power4 nap fixup in C

From: Christophe Leroy <hidden>
Date: 2021-03-16 07:16:56


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

Signed-off-by: Nicholas Piggin <npiggin@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 ?
quoted hunk
+	}
+#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);
...
quoted hunk
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

Re: [PATCH] powerpc/64s: power4 nap fixup in C

From: Nicholas Piggin <npiggin@gmail.com>
Date: 2021-03-16 08:12:22

Excerpts from Christophe Leroy's message of March 16, 2021 5:16 pm:

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

Signed-off-by: Nicholas Piggin <npiggin@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 ?
It is supposed to keep the return branch predictor balanced.

I don't know if these CPUs have one, if it gets lost during nap, or if 
nap latency is so high it really doesn't matter. But I think it is good
practice to make a habit of keeping things balanced.

Thanks,
Nick

Re: [PATCH] powerpc/64s: power4 nap fixup in C

From: Michael Ellerman <mpe@ellerman.id.au>
Date: 2021-03-29 04:41:15

Nicholas Piggin [off-list ref] writes:
There is no need for this to be in asm, use the new intrrupt entry wrapper.

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

Next time someone is in the office I'll ask them to check the display to
see if there's an oops.

cheers

Re: [PATCH] powerpc/64s: power4 nap fixup in C

From: Benjamin Herrenschmidt <benh@kernel.crashing.org>
Date: 2021-03-29 08:35:50

On Fri, 2021-03-12 at 11:20 +1000, Nicholas Piggin wrote:
+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;
+       }
Is this a pointer to a function descriptor or the actual code ?

Cheers,
Ben.
quoted hunk
+#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/include/asm/processor.h b/arch/powerpc/include/asm/processor.h

index 8acc3590c971..eedc3c775141 100644

--- a/arch/powerpc/include/asm/processor.h

+++ b/arch/powerpc/include/asm/processor.h
@@ -393,6 +393,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);

+void power4_idle_nap_return(void);

 #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 386d576673a1..bf137151100b 100644

--- a/arch/powerpc/include/asm/thread_info.h

+++ b/arch/powerpc/include/asm/thread_info.h
@@ -152,6 +152,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 60d3051a8bc8..ea7a443488d2 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.
@@ -1248,7 +1229,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
@@ -1571,7 +1551,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
@@ -1801,7 +1780,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
@@ -1886,7 +1864,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
@@ -2237,7 +2214,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
@@ -2266,7 +2242,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
@@ -2299,7 +2274,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
@@ -2345,7 +2319,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
@@ -3096,24 +3069,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 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

--
2.23.0

Re: [PATCH] powerpc/64s: power4 nap fixup in C

From: Christophe Leroy <hidden>
Date: 2021-03-29 09:05:47


Le 29/03/2021 à 10:33, Benjamin Herrenschmidt a écrit :
On Fri, 2021-03-12 at 11:20 +1000, Nicholas Piggin wrote:
quoted
+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;
+       }
Is this a pointer to a function descriptor or the actual code ?
--- 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

Re: [PATCH] powerpc/64s: power4 nap fixup in C

From: Michael Ellerman <hidden>
Date: 2021-04-10 14:34:43

On Fri, 12 Mar 2021 11:20:44 +1000, Nicholas Piggin wrote:
There is no need for this to be in asm, use the new intrrupt entry wrapper.
Applied to powerpc/next.

[1/1] powerpc/64s: power4 nap fixup in C
      https://git.kernel.org/powerpc/c/98db179a78dd8379e9d2cbfc3f00224168a9344c

cheers

Re: [PATCH] powerpc/64s: power4 nap fixup in C

From: Michael Ellerman <mpe@ellerman.id.au>
Date: 2021-04-19 05:16:46

Michael Ellerman [off-list ref] writes:
On Fri, 12 Mar 2021 11:20:44 +1000, Nicholas Piggin wrote:
quoted
There is no need for this to be in asm, use the new intrrupt entry wrapper.
Applied to powerpc/next.

[1/1] powerpc/64s: power4 nap fixup in C
      https://git.kernel.org/powerpc/c/98db179a78dd8379e9d2cbfc3f00224168a9344c
Script is drunk again, v2 was applied, not this one.

cheers
Keyboard shortcuts
hback out one level
jnext message in thread
kprevious message in thread
ldrill in
Escclose help / fold thread tree
?toggle this help