Patch "s390: fix transactional execution control register handling" has been added to the 4.9-stable tree
Subsystems (2)
This is a note to let you know that I've just added the patch titled
s390: fix transactional execution control register handling
to the 4.9-stable tree which can be found at:
http://www.kernel.org/git/?p=linux/kernel/git/stable/stable-queue.git;a=summary
The filename of the patch is:
s390-fix-transactional-execution-control-register-handling.patch
and it can be found in the queue-4.9 subdirectory.
If you, or anyone else, feels it should not be added to the stable tree, please let <[email protected]> know about it.
Quoted 1 line
From
a1c5befc1c24eb9c1ee83f711e0f21ee79cbb556Mon Sep 17 00:00:00 2001
From: Heiko Carstens <[email protected]>
Date: Thu, 9 Nov 2017 12:29:34 +0100
Subject: s390: fix transactional execution control register handling
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
From: Heiko Carstens <[email protected]>
commit a1c5befc1c24eb9c1ee83f711e0f21ee79cbb556 upstream.
Dan Horák reported the following crash related to transactional execution:
User process fault: interruption code 0013 ilc:3 in libpthread-2.26.so[3ff93c00000+1b000]
CPU: 2 PID: 1 Comm: /init Not tainted 4.13.4-300.fc27.s390x #1
Hardware name: IBM 2827 H43 400 (z/VM 6.4.0)
task: 00000000fafc8000 task.stack: 00000000fafc4000
User PSW : 0705200180000000 000003ff93c14e70
R:0 T:1 IO:1 EX:1 Key:0 M:1 W:0 P:1 AS:0 CC:2 PM:0 RI:0 EA:3
User GPRS: 0000000000000077 000003ff00000000 000003ff93144d48 000003ff93144d5e
0000000000000000 0000000000000002 0000000000000000 000003ff00000000
0000000000000000 0000000000000418 0000000000000000 000003ffcc9fe770
000003ff93d28f50 000003ff9310acf0 000003ff92b0319a 000003ffcc9fe6d0
User Code: 000003ff93c14e62: 60e0b030 std %f14,48(%r11)
000003ff93c14e66: 60f0b038 std %f15,56(%r11)
#000003ff93c14e6a: e5600000ff0e tbegin 0,65294
>000003ff93c14e70: a7740006 brc 7,3ff93c14e7c
000003ff93c14e74: a7080000 lhi %r0,0
000003ff93c14e78: a7f40023 brc 15,3ff93c14ebe
000003ff93c14e7c: b2220000 ipm %r0
000003ff93c14e80: 8800001c srl %r0,28There are several bugs with control register handling with respect to transactional execution:
- on task switch update_per_regs() is only called if the next task has an mm (is not a kernel thread). This however is incorrect. This breaks e.g. for user mode helper handling, where the kernel creates a kernel thread and then execve's a user space program. Control register contents related to transactional execution won't be updated on execve. If the previous task ran with transactional execution disabled then the new task will also run with transactional execution disabled, which is incorrect. Therefore call update_per_regs() unconditionally within switch_to().
- on startup the transactional execution facility is not enabled for the idle thread. This is not really a bug, but an inconsistency to other facilities. Therefore enable the facility if it is available.
- on fork the new thread's per_flags field is not cleared. This means that a child process inherits the PER_FLAG_NO_TE flag. This flag can be set with a ptrace request to disable transactional execution for the current process. It should not be inherited by new child processes in order to be consistent with the handling of all other PER related debugging options. Therefore clear the per_flags field in copy_thread_tls().
--- arch/s390/include/asm/switch_to.h | 2 +- arch/s390/kernel/early.c | 4 +++- arch/s390/kernel/process.c | 1 + 3 files changed, 5 insertions(+), 2 deletions(-)
arch/s390/include/asm/switch_to.h +1 -1
@@ -34,8 +34,8 @@ static inline void restore_access_regs(usave_access_regs (&prev->thread.acrs[0 ]); \save_ri_cb (prev->thread.ri_cb); \ } \ +update_cr_regs (next); \if (next->mm) { \ -update_cr_regs (next); \set_cpu_flag (CIF_FPU ); \restore_access_regs (&next->thread.acrs[0 ]); \restore_ri_cb (next->thread.ri_cb, prev->thread.ri_cb); \
arch/s390/kernel/early.c +3 -1
@@ -345,8 +345,10 @@ static __init void detect_machine_facili S390_lowcore.machine_flags |=MACHINE_FLAG_IDTE ;if (test_facility (40 )) S390_lowcore.machine_flags |=MACHINE_FLAG_LPP ; -if (test_facility (50 ) &&test_facility (73 )) +if (test_facility (50 ) &&test_facility (73 )) { S390_lowcore.machine_flags |=MACHINE_FLAG_TE ; +__ctl_set_bit (0 ,55 ); + }if (test_facility (51 )) S390_lowcore.machine_flags |=MACHINE_FLAG_TLB_LC ;if (test_facility (129 )) {
arch/s390/kernel/process.c +1 -0
@@ -120,6 +120,7 @@ int copy_thread(unsigned long clone_flagmemset (&p->thread.per_user,0 ,sizeof (p->thread.per_user));memset (&p->thread.per_event,0 ,sizeof (p->thread.per_event));clear_tsk_thread_flag (p,TIF_SINGLE_STEP ); + p->thread.per_flags =0 ;/* Initialize per thread user and system timer values */ ti =task_thread_info (p); ti->user_timer =0 ;
Patches currently in stable-queue which might be from [email protected] are
queue-4.9/s390-disassembler-add-missing-end-marker-for-e7-table.patch queue-4.9/s390-fix-transactional-execution-control-register-handling.patch queue-4.9/s390-runtime-instrumention-fix-possible-memory-corruption.patch