[<prev] [next>] [<thread-prev] [thread-next>] [day] [month] [year] [list]
Message-Id: <20220511120532.2228616-7-hca@linux.ibm.com>
Date: Wed, 11 May 2022 14:05:30 +0200
From: Heiko Carstens <hca@...ux.ibm.com>
To: Vasily Gorbik <gor@...ux.ibm.com>,
Alexander Gordeev <agordeev@...ux.ibm.com>,
Jonas Paulsson <paulsson@...ux.vnet.ibm.com>,
Ulrich Weigand <ulrich.weigand@...ibm.com>,
Masahiro Yamada <masahiroy@...nel.org>,
Alexander Egorenkov <egorenar@...ux.ibm.com>
Cc: Sven Schnelle <svens@...ux.ibm.com>,
Andreas Krebbel <krebbel@...ux.ibm.com>,
Nathan Chancellor <natechancellor@...il.com>,
Nick Desaulniers <ndesaulniers@...gle.com>,
linux-kernel@...r.kernel.org, linux-s390@...r.kernel.org
Subject: [PATCH 6/8] s390/boot: workaround llvm IAS bug
For at least the mvc and clc instructions llvm's integrated assembler can
generate incorrect code. In particular this happens with decompressor boot
code. The reason seems to be that relocations for the second displacement
of each instruction are at incorrect locations (-/+: gas vs llvm IAS):
mvc __LC_IO_NEW_PSW(16),.Lnewpsw
results in
4: d2 0f 01 f0 00 00 mvc 496(16,%r0),0
- 8: R_390_12 .head.text+0x10
+ 6: R_390_12 .head.text+0x10
and
clc 0(3,%r4),.L_hdr
results in
258: d5 02 40 00 00 00 clc 0(3,%r4),0
- 25c: R_390_12 .head.text+0x324
+ 25a: R_390_12 .head.text+0x324
Workaround this by writing the code in a different way.
Signed-off-by: Heiko Carstens <hca@...ux.ibm.com>
---
arch/s390/boot/head.S | 34 +++++++++++++++++++++-------------
1 file changed, 21 insertions(+), 13 deletions(-)
diff --git a/arch/s390/boot/head.S b/arch/s390/boot/head.S
index 2ced90172680..8402e1cd133b 100644
--- a/arch/s390/boot/head.S
+++ b/arch/s390/boot/head.S
@@ -42,7 +42,8 @@ ipl_start:
# subroutine to wait for end I/O
#
.Lirqwait:
- mvc __LC_IO_NEW_PSW(16),.Lnewpsw # set up IO interrupt psw
+ larl %r13,.Lnewpsw # set up IO interrupt psw
+ mvc __LC_IO_NEW_PSW(16),0(%r13)
lpsw .Lwaitpsw
.Lioint:
br %r14
@@ -155,9 +156,11 @@ ipl_start:
lr %r2,%r3
.Lnotrunc:
l %r4,.Linitrd
- clc 0(3,%r4),.L_hdr # if it is HDRx
+ larl %r13,.L_hdr
+ clc 0(3,%r4),0(%r13) # if it is HDRx
bz .Lagain1 # skip dataset header
- clc 0(3,%r4),.L_eof # if it is EOFx
+ larl %r13,.L_eof
+ clc 0(3,%r4),0(%r13) # if it is EOFx
bz .Lagain1 # skip dateset trailer
lr %r5,%r2
@@ -181,9 +184,11 @@ ipl_start:
.Lrdcont:
l %r2,.Linitrd
- clc 0(3,%r2),.L_hdr # skip HDRx and EOFx
+ larl %r13,.L_hdr # skip HDRx and EOFx
+ clc 0(3,%r2),0(%r13)
bz .Lagain2
- clc 0(3,%r2),.L_eof
+ larl %r13,.L_eof
+ clc 0(3,%r2),0(%r13)
bz .Lagain2
#
@@ -260,20 +265,23 @@ SYM_CODE_START_LOCAL(startup_normal)
.fill 16,4,0x0
0: lmh %r0,%r15,0(%r13) # clear high-order half of gprs
sam64 # switch to 64 bit addressing mode
- basr %r13,0 # get base
-.LPG0:
- mvc __LC_EXT_NEW_PSW(16),.Lext_new_psw-.LPG0(%r13)
- mvc __LC_PGM_NEW_PSW(16),.Lpgm_new_psw-.LPG0(%r13)
- mvc __LC_IO_NEW_PSW(16),.Lio_new_psw-.LPG0(%r13)
+ larl %r13,.Lext_new_psw
+ mvc __LC_EXT_NEW_PSW(16),0(%r13)
+ larl %r13,.Lpgm_new_psw
+ mvc __LC_PGM_NEW_PSW(16),0(%r13)
+ larl %r13,.Lio_new_psw
+ mvc __LC_IO_NEW_PSW(16),0(%r13)
xc 0x200(256),0x200 # partially clear lowcore
xc 0x300(256),0x300
xc 0xe00(256),0xe00
xc 0xf00(256),0xf00
- lctlg %c0,%c15,.Lctl-.LPG0(%r13) # load control registers
+ larl %r13,.Lctl
+ lctlg %c0,%c15,0(%r13) # load control registers
stcke __LC_BOOT_CLOCK
mvc __LC_LAST_UPDATE_CLOCK(8),__LC_BOOT_CLOCK+1
- spt 6f-.LPG0(%r13)
- mvc __LC_LAST_UPDATE_TIMER(8),6f-.LPG0(%r13)
+ larl %r13,6f
+ spt 0(%r13)
+ mvc __LC_LAST_UPDATE_TIMER(8),0(%r13)
larl %r15,_stack_end-STACK_FRAME_OVERHEAD
brasl %r14,sclp_early_setup_buffer
brasl %r14,verify_facilities
--
2.32.0
Powered by blists - more mailing lists