Skip to content

Commit fe1952f

Browse files
committed
powerpc: Rework runlatch code
This moves the inlines into system.h and changes the runlatch code to use the thread local flags (non-atomic) rather than the TIF flags (atomic) to keep track of the latch state. The code to turn it back on in an asynchronous interrupt is now simplified and partially inlined. Signed-off-by: Benjamin Herrenschmidt <[email protected]>
1 parent 7450f6f commit fe1952f

File tree

6 files changed

+89
-57
lines changed

6 files changed

+89
-57
lines changed

arch/powerpc/include/asm/exception-64s.h

Lines changed: 27 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -284,35 +284,39 @@ label##_hv: \
284284
rlwimi r11,r12,0,MSR_EE; \
285285
mtmsrd r11,1
286286

287-
#define STD_EXCEPTION_COMMON(trap, label, hdlr) \
288-
.align 7; \
289-
.globl label##_common; \
290-
label##_common: \
291-
EXCEPTION_PROLOG_COMMON(trap, PACA_EXGEN); \
292-
DISABLE_INTS; \
293-
bl .save_nvgprs; \
294-
addi r3,r1,STACK_FRAME_OVERHEAD; \
295-
bl hdlr; \
296-
b .ret_from_except
287+
#define ADD_NVGPRS \
288+
bl .save_nvgprs
289+
290+
#define RUNLATCH_ON \
291+
BEGIN_FTR_SECTION \
292+
clrrdi r3,r1,THREAD_SHIFT; \
293+
ld r4,TI_LOCAL_FLAGS(r3); \
294+
andi. r0,r4,_TLF_RUNLATCH; \
295+
beql ppc64_runlatch_on_trampoline; \
296+
END_FTR_SECTION_IFSET(CPU_FTR_CTRL)
297+
298+
#define EXCEPTION_COMMON(trap, label, hdlr, ret, additions) \
299+
.align 7; \
300+
.globl label##_common; \
301+
label##_common: \
302+
EXCEPTION_PROLOG_COMMON(trap, PACA_EXGEN); \
303+
additions; \
304+
addi r3,r1,STACK_FRAME_OVERHEAD; \
305+
bl hdlr; \
306+
b ret
307+
308+
#define STD_EXCEPTION_COMMON(trap, label, hdlr) \
309+
EXCEPTION_COMMON(trap, label, hdlr, ret_from_except, \
310+
ADD_NVGPRS;DISABLE_INTS)
297311

298312
/*
299313
* Like STD_EXCEPTION_COMMON, but for exceptions that can occur
300314
* in the idle task and therefore need the special idle handling
301315
* (finish nap and runlatch)
302316
*/
303-
#define STD_EXCEPTION_COMMON_ASYNC(trap, label, hdlr) \
304-
.align 7; \
305-
.globl label##_common; \
306-
label##_common: \
307-
EXCEPTION_PROLOG_COMMON(trap, PACA_EXGEN); \
308-
FINISH_NAP; \
309-
DISABLE_INTS; \
310-
BEGIN_FTR_SECTION \
311-
bl .ppc64_runlatch_on; \
312-
END_FTR_SECTION_IFSET(CPU_FTR_CTRL) \
313-
addi r3,r1,STACK_FRAME_OVERHEAD; \
314-
bl hdlr; \
315-
b .ret_from_except_lite
317+
#define STD_EXCEPTION_COMMON_ASYNC(trap, label, hdlr) \
318+
EXCEPTION_COMMON(trap, label, hdlr, ret_from_except_lite, \
319+
FINISH_NAP;RUNLATCH_ON;DISABLE_INTS)
316320

317321
/*
318322
* When the idle code in power4_idle puts the CPU into NAP mode,

arch/powerpc/include/asm/reg.h

Lines changed: 2 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -1079,30 +1079,12 @@
10791079

10801080
#define proc_trap() asm volatile("trap")
10811081

1082-
#ifdef CONFIG_PPC64
1083-
1084-
extern void ppc64_runlatch_on(void);
1085-
extern void __ppc64_runlatch_off(void);
1086-
1087-
#define ppc64_runlatch_off() \
1088-
do { \
1089-
if (cpu_has_feature(CPU_FTR_CTRL) && \
1090-
test_thread_flag(TIF_RUNLATCH)) \
1091-
__ppc64_runlatch_off(); \
1092-
} while (0)
1082+
#define __get_SP() ({unsigned long sp; \
1083+
asm volatile("mr %0,1": "=r" (sp)); sp;})
10931084

10941085
extern unsigned long scom970_read(unsigned int address);
10951086
extern void scom970_write(unsigned int address, unsigned long value);
10961087

1097-
#else
1098-
#define ppc64_runlatch_on()
1099-
#define ppc64_runlatch_off()
1100-
1101-
#endif /* CONFIG_PPC64 */
1102-
1103-
#define __get_SP() ({unsigned long sp; \
1104-
asm volatile("mr %0,1": "=r" (sp)); sp;})
1105-
11061088
struct pt_regs;
11071089

11081090
extern void ppc_save_regs(struct pt_regs *regs);

arch/powerpc/include/asm/system.h

Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -550,5 +550,43 @@ extern void reloc_got2(unsigned long);
550550

551551
extern struct dentry *powerpc_debugfs_root;
552552

553+
#ifdef CONFIG_PPC64
554+
555+
extern void __ppc64_runlatch_on(void);
556+
extern void __ppc64_runlatch_off(void);
557+
558+
/*
559+
* We manually hard enable-disable, this is called
560+
* in the idle loop and we don't want to mess up
561+
* with soft-disable/enable & interrupt replay.
562+
*/
563+
#define ppc64_runlatch_off() \
564+
do { \
565+
if (cpu_has_feature(CPU_FTR_CTRL) && \
566+
test_thread_local_flags(_TLF_RUNLATCH)) { \
567+
unsigned long msr = mfmsr(); \
568+
__hard_irq_disable(); \
569+
__ppc64_runlatch_off(); \
570+
if (msr & MSR_EE) \
571+
__hard_irq_enable(); \
572+
} \
573+
} while (0)
574+
575+
#define ppc64_runlatch_on() \
576+
do { \
577+
if (cpu_has_feature(CPU_FTR_CTRL) && \
578+
!test_thread_local_flags(_TLF_RUNLATCH)) { \
579+
unsigned long msr = mfmsr(); \
580+
__hard_irq_disable(); \
581+
__ppc64_runlatch_on(); \
582+
if (msr & MSR_EE) \
583+
__hard_irq_enable(); \
584+
} \
585+
} while (0)
586+
#else
587+
#define ppc64_runlatch_on()
588+
#define ppc64_runlatch_off()
589+
#endif /* CONFIG_PPC64 */
590+
553591
#endif /* __KERNEL__ */
554592
#endif /* _ASM_POWERPC_SYSTEM_H */

arch/powerpc/include/asm/thread_info.h

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -110,7 +110,6 @@ static inline struct thread_info *current_thread_info(void)
110110
#define TIF_NOERROR 12 /* Force successful syscall return */
111111
#define TIF_NOTIFY_RESUME 13 /* callback before returning to user */
112112
#define TIF_SYSCALL_TRACEPOINT 15 /* syscall tracepoint instrumentation */
113-
#define TIF_RUNLATCH 16 /* Is the runlatch enabled? */
114113

115114
/* as above, but as bit values */
116115
#define _TIF_SYSCALL_TRACE (1<<TIF_SYSCALL_TRACE)
@@ -141,11 +140,13 @@ static inline struct thread_info *current_thread_info(void)
141140
#define TLF_SLEEPING 1 /* suspend code enabled SLEEP mode */
142141
#define TLF_RESTORE_SIGMASK 2 /* Restore signal mask in do_signal */
143142
#define TLF_LAZY_MMU 3 /* tlb_batch is active */
143+
#define TLF_RUNLATCH 4 /* Is the runlatch enabled? */
144144

145145
#define _TLF_NAPPING (1 << TLF_NAPPING)
146146
#define _TLF_SLEEPING (1 << TLF_SLEEPING)
147147
#define _TLF_RESTORE_SIGMASK (1 << TLF_RESTORE_SIGMASK)
148148
#define _TLF_LAZY_MMU (1 << TLF_LAZY_MMU)
149+
#define _TLF_RUNLATCH (1 << TLF_RUNLATCH)
149150

150151
#ifndef __ASSEMBLY__
151152
#define HAVE_SET_RESTORE_SIGMASK 1
@@ -156,6 +157,12 @@ static inline void set_restore_sigmask(void)
156157
set_bit(TIF_SIGPENDING, &ti->flags);
157158
}
158159

160+
static inline bool test_thread_local_flags(unsigned int flags)
161+
{
162+
struct thread_info *ti = current_thread_info();
163+
return (ti->local_flags & flags) != 0;
164+
}
165+
159166
#ifdef CONFIG_PPC64
160167
#define is_32bit_task() (test_thread_flag(TIF_32BIT))
161168
#else

arch/powerpc/kernel/exceptions-64s.S

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -483,6 +483,9 @@ machine_check_common:
483483
system_call_entry:
484484
b system_call_common
485485

486+
ppc64_runlatch_on_trampoline:
487+
b .__ppc64_runlatch_on
488+
486489
/*
487490
* Here we have detected that the kernel stack pointer is bad.
488491
* R9 contains the saved CR, r13 points to the paca,

arch/powerpc/kernel/process.c

Lines changed: 11 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -1220,34 +1220,32 @@ void dump_stack(void)
12201220
EXPORT_SYMBOL(dump_stack);
12211221

12221222
#ifdef CONFIG_PPC64
1223-
void ppc64_runlatch_on(void)
1223+
/* Called with hard IRQs off */
1224+
void __ppc64_runlatch_on(void)
12241225
{
1226+
struct thread_info *ti = current_thread_info();
12251227
unsigned long ctrl;
12261228

1227-
if (cpu_has_feature(CPU_FTR_CTRL) && !test_thread_flag(TIF_RUNLATCH)) {
1228-
HMT_medium();
1229-
1230-
ctrl = mfspr(SPRN_CTRLF);
1231-
ctrl |= CTRL_RUNLATCH;
1232-
mtspr(SPRN_CTRLT, ctrl);
1229+
ctrl = mfspr(SPRN_CTRLF);
1230+
ctrl |= CTRL_RUNLATCH;
1231+
mtspr(SPRN_CTRLT, ctrl);
12331232

1234-
set_thread_flag(TIF_RUNLATCH);
1235-
}
1233+
ti->local_flags |= TLF_RUNLATCH;
12361234
}
12371235

1236+
/* Called with hard IRQs off */
12381237
void __ppc64_runlatch_off(void)
12391238
{
1239+
struct thread_info *ti = current_thread_info();
12401240
unsigned long ctrl;
12411241

1242-
HMT_medium();
1243-
1244-
clear_thread_flag(TIF_RUNLATCH);
1242+
ti->local_flags &= ~TLF_RUNLATCH;
12451243

12461244
ctrl = mfspr(SPRN_CTRLF);
12471245
ctrl &= ~CTRL_RUNLATCH;
12481246
mtspr(SPRN_CTRLT, ctrl);
12491247
}
1250-
#endif
1248+
#endif /* CONFIG_PPC64 */
12511249

12521250
#if THREAD_SHIFT < PAGE_SHIFT
12531251

0 commit comments

Comments
 (0)