The purpose of this series is to implement a fast syscall entry
on ppc32, as already done on ppc64.
Unlike all other exceptions which can happen at any time and
require to preserve all registers, the syscalls do not
require the preservation of volatile registers (except LR).
Syscall entries can then be optimised with lighter entry code
than the general exception handling.
In the meantime this series refactorises the exception entry on
40x/6xx/8xx as they are pretty similar, and it takes benh series
on rationalising the settings of MSR_EE at exceptions/syscall entries
as this change pretty simplies exception entries.
The refactorisation of exception entry will help when it comes to
implementing VMAP_STACK
On a 8xx, this series improves null_syscall selftest by 17%
On a 83xx, this series improves null_syscall selftest by 12,5%
v3:
- Rebased on latest powerpc/merge branch
- Fixed trivial conflict due to KUP functionnality
- Dropped patch 15 (already applied)
v2:
- Rebased on latest powerpc/merge branch.
- Added booke support as well (tested on qemu bamboo).
- Added a patch to get rid of the dummy frames when calling trace_hardirqs_on/off.
Christophe Leroy (16):
powerpc/32: Refactor EXCEPTION entry macros for head_8xx.S and
head_32.S
powerpc/32: move LOAD_MSR_KERNEL() into head_32.h and use it
powerpc/32: make the 6xx/8xx EXC_XFER_TEMPLATE() similar to the
40x/booke one
powerpc/40x: Don't use SPRN_SPRG_SCRATCH2 in EXCEPTION_PROLOG
powerpc/40x: add exception frame marker
powerpc/40x: Split and rename NORMAL_EXCEPTION_PROLOG
powerpc/40x: Refactor exception entry macros by using head_32.h
powerpc/fsl_booke: ensure SPEFloatingPointException() reenables
interrupts
powerpc/32: enter syscall with MSR_EE inconditionaly set
powerpc/32: Enter exceptions with MSR_EE unset
powerpc/32: get rid of COPY_EE in exception entry
powerpc: Fix 32-bit handling of MSR_EE on exceptions
powerpc/32: implement fast entry for syscalls on non BOOKE
powerpc/32: implement fast entry for syscalls on BOOKE
powerpc/32: don't do syscall stuff in transfer_to_handler
powerpc/32: Don't add dummy frames when calling trace_hardirqs_on/off
arch/powerpc/kernel/entry_32.S | 153 +++++++++++++-------------
arch/powerpc/kernel/head_32.S | 170 +++++++----------------------
arch/powerpc/kernel/head_32.h | 203 +++++++++++++++++++++++++++++++++++
arch/powerpc/kernel/head_40x.S | 152 +++++++-------------------
arch/powerpc/kernel/head_44x.S | 9 +-
arch/powerpc/kernel/head_8xx.S | 133 ++++-------------------
arch/powerpc/kernel/head_booke.h | 131 +++++++++++++++++-----
arch/powerpc/kernel/head_fsl_booke.S | 29 +++--
arch/powerpc/kernel/traps.c | 8 ++
9 files changed, 508 insertions(+), 480 deletions(-)
create mode 100644 arch/powerpc/kernel/head_32.h
--
2.13.3
SPEFloatingPointException() is the only exception handler which 'forgets' to
re-enable interrupts. This patch makes sure it does.
Suggested-by: Benjamin Herrenschmidt <[email protected]>
Signed-off-by: Christophe Leroy <[email protected]>
---
arch/powerpc/kernel/traps.c | 8 ++++++++
1 file changed, 8 insertions(+)
diff --git a/arch/powerpc/kernel/traps.c b/arch/powerpc/kernel/traps.c
index 1fd45a8650e1..665f294725cb 100644
--- a/arch/powerpc/kernel/traps.c
+++ b/arch/powerpc/kernel/traps.c
@@ -2088,6 +2088,10 @@ void SPEFloatingPointException(struct pt_regs *regs)
int code = FPE_FLTUNK;
int err;
+ /* We restore the interrupt state now */
+ if (!arch_irq_disabled_regs(regs))
+ local_irq_enable();
+
flush_spe_to_thread(current);
spefscr = current->thread.spefscr;
@@ -2133,6 +2137,10 @@ void SPEFloatingPointRoundException(struct pt_regs *regs)
extern int speround_handler(struct pt_regs *regs);
int err;
+ /* We restore the interrupt state now */
+ if (!arch_irq_disabled_regs(regs))
+ local_irq_enable();
+
preempt_disable();
if (regs->msr & MSR_SPE)
giveup_spe(current);
--
2.13.3
This patch adds STACK_FRAME_REGS_MARKER in the stack at exception entry
in order to see interrupts in call traces as below:
[ 0.013964] Call Trace:
[ 0.014014] [c0745db0] [c007a9d4] tick_periodic.constprop.5+0xd8/0x104 (unreliable)
[ 0.014086] [c0745dc0] [c007aa20] tick_handle_periodic+0x20/0x9c
[ 0.014181] [c0745de0] [c0009cd0] timer_interrupt+0xa0/0x264
[ 0.014258] [c0745e10] [c000e484] ret_from_except+0x0/0x14
[ 0.014390] --- interrupt: 901 at console_unlock.part.7+0x3f4/0x528
[ 0.014390] LR = console_unlock.part.7+0x3f0/0x528
[ 0.014455] [c0745ee0] [c0050334] console_unlock.part.7+0x114/0x528 (unreliable)
[ 0.014542] [c0745f30] [c00524e0] register_console+0x3d8/0x44c
[ 0.014625] [c0745f60] [c0675aac] cpm_uart_console_init+0x18/0x2c
[ 0.014709] [c0745f70] [c06614f4] console_init+0x114/0x1cc
[ 0.014795] [c0745fb0] [c0658b68] start_kernel+0x300/0x3d8
[ 0.014864] [c0745ff0] [c00022cc] start_here+0x44/0x98
Signed-off-by: Christophe Leroy <[email protected]>
---
arch/powerpc/kernel/head_40x.S | 6 ++++++
1 file changed, 6 insertions(+)
diff --git a/arch/powerpc/kernel/head_40x.S b/arch/powerpc/kernel/head_40x.S
index f49b0278e995..cb95a5c17cea 100644
--- a/arch/powerpc/kernel/head_40x.S
+++ b/arch/powerpc/kernel/head_40x.S
@@ -132,6 +132,9 @@ _ENTRY(saved_ksp_limit)
tovirt(r1,r11); /* set new kernel sp */ \
rlwinm r9,r9,0,14,12; /* clear MSR_WE (necessary?) */\
stw r0,GPR0(r11); \
+ lis r10, STACK_FRAME_REGS_MARKER@ha; /* exception frame marker */\
+ addi r10, r10, STACK_FRAME_REGS_MARKER@l; \
+ stw r10, 8(r11); \
SAVE_4GPRS(3, r11); \
SAVE_2GPRS(7, r11)
@@ -174,6 +177,9 @@ _ENTRY(saved_ksp_limit)
tovirt(r1,r11); \
rlwinm r9,r9,0,14,12; /* clear MSR_WE (necessary?) */\
stw r0,GPR0(r11); \
+ lis r10, STACK_FRAME_REGS_MARKER@ha; /* exception frame marker */\
+ addi r10, r10, STACK_FRAME_REGS_MARKER@l; \
+ stw r10, 8(r11); \
SAVE_4GPRS(3, r11); \
SAVE_2GPRS(7, r11)
--
2.13.3