Applied: [PATCH Trusty SRU v2] powerpc/tm: backport b4b56f to Abort syscalls in active transactions
Kamal Mostafa
kamal at canonical.com
Tue Jun 14 17:04:55 UTC 2016
Applied to Trusty, but (same as for the other releases)...
On Fri, Jun 10, 2016 at 07:08:16AM -0600, Tim Gardner wrote:
> From: Simon Guo <simonguo at linux.vnet.ibm.com>
Replaced that ^^ with the correct author of the patch (Sam bobroff)
and the patch title and description with those from mainline
b4b56f9ecab40f3b4ef53e130c9f6663be491894.
-Kamal
>
> BugLink: http://bugs.launchpad.net/bugs/1572624
>
> This patch backport b4b56f9ecab40f3b to Ubuntu 14.04.04.
>
> quoted from original commit:
> It is about changing the syscall handler to doom (tabort) active
> transactions when a syscall is made and return very early without
> performing the syscall and keeping side effects to a minimum (no CPU
> accounting or system call tracing is performed). Also included is a
> new HWCAP2 bit, PPC_FEATURE2_HTM_NOSC, to indicate this
> behaviour to userspace.
>
> Without this backport patch, app running TM testing on Ubuntu 14.04
> might hang. Glibc with TLE enabled will be able to bypass this issue.
> However it is not enabled on Ubunt 14.04.
>
> The issue to be addressed:
> User is creating stack structure using C++ transactional memory
> extension:
>
> int Pop(int)
> {
> int ret = 0;
> __transaction_atomic
> {
> if(!stack_.empty())
> {
> ret = stack_.top();
> stack_.pop();
> } else
> ret = -1;
> }
> return ret;
> }
>
> While evaluating if(!stack_.empty()), this code calls a libitm function
> (GCC code), which calls malloc (glibc code) which ends up calling futex
> (a syscall).
> A syscall inside a transaction is forbidden by the kernel, but there is
> nothing the user can do to avoid this syscall.
>
> This will hang the user application inside the malloc(), which would be
> waiting for the futex to return.
>
> Ubuntu 14.04 provides glibc 2.19, which is too old to know about HTM.
> And this is probably happening with other libraries as well.
>
> Signed-off-by: Simon Guo <simonguo at linux.vnet.ibm.com>
> Signed-off-by: Tim Gardner <tim.gardner at canonical.com>
> ---
> Documentation/powerpc/transactional_memory.txt | 32 +++++++++++------------
> arch/powerpc/include/asm/cputable.h | 10 +++++---
> arch/powerpc/include/uapi/asm/cputable.h | 1 +
> arch/powerpc/include/uapi/asm/tm.h | 2 +-
> arch/powerpc/kernel/cputable.c | 4 ++-
> arch/powerpc/kernel/entry_64.S | 35 ++++++++++++++++++++++++++
> 6 files changed, 62 insertions(+), 22 deletions(-)
>
> diff --git a/Documentation/powerpc/transactional_memory.txt b/Documentation/powerpc/transactional_memory.txt
> index dc23e58..8307112 100644
> --- a/Documentation/powerpc/transactional_memory.txt
> +++ b/Documentation/powerpc/transactional_memory.txt
> @@ -74,22 +74,23 @@ Causes of transaction aborts
> Syscalls
> ========
>
> -Performing syscalls from within transaction is not recommended, and can lead
> -to unpredictable results.
> +Syscalls made from within an active transaction will not be performed and the
> +transaction will be doomed by the kernel with the failure code TM_CAUSE_SYSCALL
> +| TM_CAUSE_PERSISTENT.
>
> -Syscalls do not by design abort transactions, but beware: The kernel code will
> -not be running in transactional state. The effect of syscalls will always
> -remain visible, but depending on the call they may abort your transaction as a
> -side-effect, read soon-to-be-aborted transactional data that should not remain
> -invisible, etc. If you constantly retry a transaction that constantly aborts
> -itself by calling a syscall, you'll have a livelock & make no progress.
> +Syscalls made from within a suspended transaction are performed as normal and
> +the transaction is not explicitly doomed by the kernel. However, what the
> +kernel does to perform the syscall may result in the transaction being doomed
> +by the hardware. The syscall is performed in suspended mode so any side
> +effects will be persistent, independent of transaction success or failure. No
> +guarantees are provided by the kernel about which syscalls will affect
> +transaction success.
>
> -Simple syscalls (e.g. sigprocmask()) "could" be OK. Even things like write()
> -from, say, printf() should be OK as long as the kernel does not access any
> -memory that was accessed transactionally.
> -
> -Consider any syscalls that happen to work as debug-only -- not recommended for
> -production use. Best to queue them up till after the transaction is over.
> +Care must be taken when relying on syscalls to abort during active transactions
> +if the calls are made via a library. Libraries may cache values (which may
> +give the appearance of success) or perform operations that cause transaction
> +failure before entering the kernel (which may produce different failure codes).
> +Examples are glibc's getpid() and lazy symbol resolution.
>
>
> Signals
> @@ -176,8 +177,7 @@ kernel aborted a transaction:
> TM_CAUSE_RESCHED Thread was rescheduled.
> TM_CAUSE_TLBI Software TLB invalide.
> TM_CAUSE_FAC_UNAV FP/VEC/VSX unavailable trap.
> - TM_CAUSE_SYSCALL Currently unused; future syscalls that must abort
> - transactions for consistency will use this.
> + TM_CAUSE_SYSCALL Syscall from active transaction.
> TM_CAUSE_SIGNAL Signal delivered.
> TM_CAUSE_MISC Currently unused.
> TM_CAUSE_ALIGNMENT Alignment fault.
> diff --git a/arch/powerpc/include/asm/cputable.h b/arch/powerpc/include/asm/cputable.h
> index bc23477..c980f6d 100644
> --- a/arch/powerpc/include/asm/cputable.h
> +++ b/arch/powerpc/include/asm/cputable.h
> @@ -237,11 +237,13 @@ extern const char *powerpc_base_platform;
>
> /* We only set the TM feature if the kernel was compiled with TM supprt */
> #ifdef CONFIG_PPC_TRANSACTIONAL_MEM
> -#define CPU_FTR_TM_COMP CPU_FTR_TM
> -#define PPC_FEATURE2_HTM_COMP PPC_FEATURE2_HTM
> +#define CPU_FTR_TM_COMP CPU_FTR_TM
> +#define PPC_FEATURE2_HTM_COMP PPC_FEATURE2_HTM
> +#define PPC_FEATURE2_HTM_NOSC_COMP PPC_FEATURE2_HTM_NOSC
> #else
> -#define CPU_FTR_TM_COMP 0
> -#define PPC_FEATURE2_HTM_COMP 0
> +#define CPU_FTR_TM_COMP 0
> +#define PPC_FEATURE2_HTM_COMP 0
> +#define PPC_FEATURE2_HTM_NOSC_COMP 0
> #endif
>
> /* We need to mark all pages as being coherent if we're SMP or we have a
> diff --git a/arch/powerpc/include/uapi/asm/cputable.h b/arch/powerpc/include/uapi/asm/cputable.h
> index de2c0e4..4368604 100644
> --- a/arch/powerpc/include/uapi/asm/cputable.h
> +++ b/arch/powerpc/include/uapi/asm/cputable.h
> @@ -42,5 +42,6 @@
> #define PPC_FEATURE2_ISEL 0x08000000
> #define PPC_FEATURE2_TAR 0x04000000
> #define PPC_FEATURE2_VEC_CRYPTO 0x02000000
> +#define PPC_FEATURE2_HTM_NOSC 0x01000000
>
> #endif /* _UAPI__ASM_POWERPC_CPUTABLE_H */
> diff --git a/arch/powerpc/include/uapi/asm/tm.h b/arch/powerpc/include/uapi/asm/tm.h
> index 85059a0..ce99e38 100644
> --- a/arch/powerpc/include/uapi/asm/tm.h
> +++ b/arch/powerpc/include/uapi/asm/tm.h
> @@ -9,7 +9,7 @@
> #define TM_CAUSE_RESCHED 0xde
> #define TM_CAUSE_TLBI 0xdc
> #define TM_CAUSE_FAC_UNAV 0xda
> -#define TM_CAUSE_SYSCALL 0xd8 /* future use */
> +#define TM_CAUSE_SYSCALL 0xd8
> #define TM_CAUSE_MISC 0xd6 /* future use */
> #define TM_CAUSE_SIGNAL 0xd4
> #define TM_CAUSE_ALIGNMENT 0xd2
> diff --git a/arch/powerpc/kernel/cputable.c b/arch/powerpc/kernel/cputable.c
> index 11da04a..82d91a9 100644
> --- a/arch/powerpc/kernel/cputable.c
> +++ b/arch/powerpc/kernel/cputable.c
> @@ -108,7 +108,9 @@ extern void __restore_cpu_e6500(void);
> PPC_FEATURE_TRUE_LE | \
> PPC_FEATURE_PSERIES_PERFMON_COMPAT)
> #define COMMON_USER2_POWER8 (PPC_FEATURE2_ARCH_2_07 | \
> - PPC_FEATURE2_HTM_COMP | PPC_FEATURE2_DSCR | \
> + PPC_FEATURE2_HTM_COMP | \
> + PPC_FEATURE2_HTM_NOSC_COMP | \
> + PPC_FEATURE2_DSCR | \
> PPC_FEATURE2_ISEL | PPC_FEATURE2_TAR | \
> PPC_FEATURE2_VEC_CRYPTO)
> #define COMMON_USER_PA6T (COMMON_USER_PPC64 | PPC_FEATURE_PA6T |\
> diff --git a/arch/powerpc/kernel/entry_64.S b/arch/powerpc/kernel/entry_64.S
> index 0e59fbf..145f39c 100644
> --- a/arch/powerpc/kernel/entry_64.S
> +++ b/arch/powerpc/kernel/entry_64.S
> @@ -34,6 +34,7 @@
> #include <asm/ftrace.h>
> #include <asm/hw_irq.h>
> #include <asm/context_tracking.h>
> +#include <uapi/asm/tm.h>
>
> /*
> * System calls.
> @@ -53,6 +54,12 @@ exception_marker:
>
> .globl system_call_common
> system_call_common:
> +#ifdef CONFIG_PPC_TRANSACTIONAL_MEM
> +BEGIN_FTR_SECTION
> + extrdi. r10, r12, 1, (63-MSR_TS_T_LG) /* transaction active? */
> + bne tabort_syscall
> +END_FTR_SECTION_IFSET(CPU_FTR_TM)
> +#endif
> andi. r10,r12,MSR_PR
> mr r10,r1
> addi r1,r1,-INT_FRAME_SIZE
> @@ -324,6 +331,34 @@ syscall_exit_work:
> bl .do_syscall_trace_leave
> b .ret_from_except
>
> +#ifdef CONFIG_PPC_TRANSACTIONAL_MEM
> +tabort_syscall:
> + /* Firstly we need to enable TM in the kernel */
> + mfmsr r10
> + li r13, 1
> + rldimi r10, r13, MSR_TM_LG, 63-MSR_TM_LG
> + mtmsrd r10, 0
> +
> + /* tabort, this dooms the transaction, nothing else */
> + li r13, (TM_CAUSE_SYSCALL|TM_CAUSE_PERSISTENT)
> + TABORT(R13)
> +
> + /*
> + * Return directly to userspace. We have corrupted user register state,
> + * but userspace will never see that register state. Execution will
> + * resume after the tbegin of the aborted transaction with the
> + * checkpointed register state.
> + */
> + li r13, MSR_RI
> + andc r10, r10, r13
> + mtmsrd r10, 1
> + mtspr SPRN_SRR0, r11
> + mtspr SPRN_SRR1, r12
> +
> + rfid
> + b . /* prevent speculative execution */
> +#endif
> +
> /* Save non-volatile GPRs, if not already saved. */
> _GLOBAL(save_nvgprs)
> ld r11,_TRAP(r1)
> --
> 1.9.1
>
>
> --
> kernel-team mailing list
> kernel-team at lists.ubuntu.com
> https://lists.ubuntu.com/mailman/listinfo/kernel-team
More information about the kernel-team
mailing list