From 6efd640b006dbce56cb91c2a9cf19bcb4a631226 Mon Sep 17 00:00:00 2001 From: Michael Neuling Date: Sun, 26 May 2013 18:09:39 +0000 Subject: [PATCH] --- yaml --- r: 376522 b: refs/heads/master c: 6ce6c629fd8254b3177650de99699682ff7f6707 h: refs/heads/master v: v3 --- [refs] | 2 +- .../powerpc/transactional_memory.txt | 7 +++-- trunk/arch/powerpc/include/asm/reg.h | 2 ++ trunk/arch/powerpc/kernel/traps.c | 29 +++++++++++++++++++ 4 files changed, 37 insertions(+), 3 deletions(-) diff --git a/[refs] b/[refs] index 09f43dfabea0..8885a5340cab 100644 --- a/[refs] +++ b/[refs] @@ -1,2 +1,2 @@ --- -refs/heads/master: 24b92375dc4ec8a15262e8aaaab60b7404d4b1e7 +refs/heads/master: 6ce6c629fd8254b3177650de99699682ff7f6707 diff --git a/trunk/Documentation/powerpc/transactional_memory.txt b/trunk/Documentation/powerpc/transactional_memory.txt index 84e04a0db0f8..c54bf3127651 100644 --- a/trunk/Documentation/powerpc/transactional_memory.txt +++ b/trunk/Documentation/powerpc/transactional_memory.txt @@ -161,9 +161,12 @@ kernel aborted a transaction: transactions for consistency will use this. TM_CAUSE_SIGNAL Signal delivered. TM_CAUSE_MISC Currently unused. + TM_CAUSE_ALIGNMENT Alignment fault. + TM_CAUSE_EMULATE Emulation that touched memory. -These can be checked by the user program's abort handler as TEXASR[0:7]. - +These can be checked by the user program's abort handler as TEXASR[0:7]. If +bit 7 is set, it indicates that the error is consider persistent. For example +a TM_CAUSE_ALIGNMENT will be persistent while a TM_CAUSE_RESCHED will not.q GDB === diff --git a/trunk/arch/powerpc/include/asm/reg.h b/trunk/arch/powerpc/include/asm/reg.h index 8f6a94b2dc99..d0528e0d6db8 100644 --- a/trunk/arch/powerpc/include/asm/reg.h +++ b/trunk/arch/powerpc/include/asm/reg.h @@ -122,6 +122,8 @@ #define TM_CAUSE_SYSCALL 0xd8 /* future use */ #define TM_CAUSE_MISC 0xd6 /* future use */ #define TM_CAUSE_SIGNAL 0xd4 +#define TM_CAUSE_ALIGNMENT 0xd2 +#define TM_CAUSE_EMULATE 0xd0 #if defined(CONFIG_PPC_BOOK3S_64) #define MSR_64BIT MSR_SF diff --git a/trunk/arch/powerpc/kernel/traps.c b/trunk/arch/powerpc/kernel/traps.c index a7a648f6b750..f18c79c324ef 100644 --- a/trunk/arch/powerpc/kernel/traps.c +++ b/trunk/arch/powerpc/kernel/traps.c @@ -53,6 +53,7 @@ #ifdef CONFIG_PPC64 #include #include +#include #endif #include #include @@ -932,6 +933,28 @@ static int emulate_isel(struct pt_regs *regs, u32 instword) return 0; } +#ifdef CONFIG_PPC_TRANSACTIONAL_MEM +static inline bool tm_abort_check(struct pt_regs *regs, int cause) +{ + /* If we're emulating a load/store in an active transaction, we cannot + * emulate it as the kernel operates in transaction suspended context. + * We need to abort the transaction. This creates a persistent TM + * abort so tell the user what caused it with a new code. + */ + if (MSR_TM_TRANSACTIONAL(regs->msr)) { + tm_enable(); + tm_abort(cause); + return true; + } + return false; +} +#else +static inline bool tm_abort_check(struct pt_regs *regs, int reason) +{ + return false; +} +#endif + static int emulate_instruction(struct pt_regs *regs) { u32 instword; @@ -971,6 +994,9 @@ static int emulate_instruction(struct pt_regs *regs) /* Emulate load/store string insn. */ if ((instword & PPC_INST_STRING_GEN_MASK) == PPC_INST_STRING) { + if (tm_abort_check(regs, + TM_CAUSE_EMULATE | TM_CAUSE_PERSISTENT)) + return -EINVAL; PPC_WARN_EMULATED(string, regs); return emulate_string_inst(regs, instword); } @@ -1148,6 +1174,9 @@ void alignment_exception(struct pt_regs *regs) if (!arch_irq_disabled_regs(regs)) local_irq_enable(); + if (tm_abort_check(regs, TM_CAUSE_ALIGNMENT | TM_CAUSE_PERSISTENT)) + goto bail; + /* we don't implement logging of alignment exceptions */ if (!(current->thread.align_ctl & PR_UNALIGN_SIGBUS)) fixed = fix_alignment(regs);