Skip to content

Commit 37e37c2

Browse files
Michael HolzheuMartin Schwidefsky
authored andcommitted
[S390] Fix stfle() lowcore protection problem
The stfle() function writes into lowcore memory when stfl_fac_list is initialized with "S390_lowcore.stfl_fac_list = 0". For older compilers this triggers a lowcore exception. With newer compilers and "-OXX" compile option the bug does not show up because the "S390_lowcore.stfl_fac_list" initialization is removed by the compiler. The reason for thatis the incorrect "=m" (S390_lowcore.stfl_fac_list) constraint in the stfl inline assembly. The following shows the disassembly of the stfle() optimized code that is inlined in the lgr_info_get() function: 000000000011325c <lgr_info_get>: 11325c: eb 9f f0 60 00 24 stmg %r9,%r15,96(%r15) 113262: c0 d0 00 29 0e 47 larl %r13,634ef0 <servi..> 113268: a7 f1 3f c0 tml %r15,16320 11326c: b9 04 00 ef lgr %r14,%r15 113270: a7 84 00 01 je 113272 <lgr_info_g..> 113274: a7 fb ff c0 aghi %r15,-64 113278: b9 04 00 c2 lgr %r12,%r2 11327c: a7 29 00 01 lghi %r2,1 113280: e3 e0 f0 98 00 24 stg %r14,152(%r15) 113286: d7 97 c0 00 c0 00 xc 0(152,%r12),0(%r12) 11328c: c0 e5 00 28 db 4c brasl %r14,62e924 <add_e..> 113292: b2 b1 00 00 stfl 0 To fix the problem we now clear the S390_lowcore.stfl_fac_list at startup in "head.S" for all machine types before lowcore protection is enabled. In addition to that the "=m" constraint is replaced by "+m". Signed-off-by: Michael Holzheu <[email protected]> Signed-off-by: Martin Schwidefsky <[email protected]>
1 parent af0ee94 commit 37e37c2

File tree

2 files changed

+2
-3
lines changed

2 files changed

+2
-3
lines changed

arch/s390/include/asm/facility.h

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -38,12 +38,11 @@ static inline void stfle(u64 *stfle_fac_list, int size)
3838
unsigned long nr;
3939

4040
preempt_disable();
41-
S390_lowcore.stfl_fac_list = 0;
4241
asm volatile(
4342
" .insn s,0xb2b10000,0(0)\n" /* stfl */
4443
"0:\n"
4544
EX_TABLE(0b, 0b)
46-
: "=m" (S390_lowcore.stfl_fac_list));
45+
: "+m" (S390_lowcore.stfl_fac_list));
4746
nr = 4; /* bytes stored by stfl */
4847
memcpy(stfle_fac_list, &S390_lowcore.stfl_fac_list, 4);
4948
if (S390_lowcore.stfl_fac_list & 0x01000000) {

arch/s390/kernel/head.S

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -474,9 +474,9 @@ ENTRY(startup_kdump)
474474
stck __LC_LAST_UPDATE_CLOCK
475475
spt 5f-.LPG0(%r13)
476476
mvc __LC_LAST_UPDATE_TIMER(8),5f-.LPG0(%r13)
477+
xc __LC_STFL_FAC_LIST(8),__LC_STFL_FAC_LIST
477478
#ifndef CONFIG_MARCH_G5
478479
# check capabilities against MARCH_{G5,Z900,Z990,Z9_109,Z10}
479-
xc __LC_STFL_FAC_LIST(8),__LC_STFL_FAC_LIST
480480
.insn s,0xb2b10000,__LC_STFL_FAC_LIST # store facility list
481481
tm __LC_STFL_FAC_LIST,0x01 # stfle available ?
482482
jz 0f

0 commit comments

Comments
 (0)