mirror of
				https://github.com/torvalds/linux.git
				synced 2025-10-31 08:38:45 +02:00 
			
		
		
		
	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.
Tested-by: Nathan Chancellor <nathan@kernel.org>
Tested-by: Nick Desaulniers <ndesaulniers@google.com>
Link: https://github.com/llvm/llvm-project/issues/55411
Link: https://lore.kernel.org/r/20220511120532.2228616-7-hca@linux.ibm.com
Signed-off-by: Heiko Carstens <hca@linux.ibm.com>
			
			
This commit is contained in:
		
							parent
							
								
									adda746629
								
							
						
					
					
						commit
						e9953b729b
					
				
					 1 changed files with 21 additions and 13 deletions
				
			
		|  | @ -42,7 +42,8 @@ ipl_start: | ||||||
| # subroutine to wait for end I/O | # subroutine to wait for end I/O | ||||||
| # | # | ||||||
| .Lirqwait: | .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 | 	lpsw	.Lwaitpsw | ||||||
| .Lioint: | .Lioint: | ||||||
| 	br	%r14 | 	br	%r14 | ||||||
|  | @ -155,9 +156,11 @@ ipl_start: | ||||||
| 	lr	%r2,%r3 | 	lr	%r2,%r3 | ||||||
| .Lnotrunc: | .Lnotrunc: | ||||||
| 	l	%r4,.Linitrd | 	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 | 	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 | 	bz	.Lagain1		# skip dateset trailer | ||||||
| 
 | 
 | ||||||
| 	lr	%r5,%r2 | 	lr	%r5,%r2 | ||||||
|  | @ -181,9 +184,11 @@ ipl_start: | ||||||
| .Lrdcont: | .Lrdcont: | ||||||
| 	l	%r2,.Linitrd | 	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 | 	bz	.Lagain2 | ||||||
| 	clc	0(3,%r2),.L_eof | 	larl	%r13,.L_eof | ||||||
|  | 	clc	0(3,%r2),0(%r13) | ||||||
| 	bz	.Lagain2 | 	bz	.Lagain2 | ||||||
| 
 | 
 | ||||||
| # | # | ||||||
|  | @ -260,20 +265,23 @@ SYM_CODE_START_LOCAL(startup_normal) | ||||||
| 	.fill	16,4,0x0 | 	.fill	16,4,0x0 | ||||||
| 0:	lmh	%r0,%r15,0(%r13)	# clear high-order half of gprs | 0:	lmh	%r0,%r15,0(%r13)	# clear high-order half of gprs | ||||||
| 	sam64				# switch to 64 bit addressing mode | 	sam64				# switch to 64 bit addressing mode | ||||||
| 	basr	%r13,0			# get base | 	larl	%r13,.Lext_new_psw | ||||||
| .LPG0: | 	mvc	__LC_EXT_NEW_PSW(16),0(%r13) | ||||||
| 	mvc	__LC_EXT_NEW_PSW(16),.Lext_new_psw-.LPG0(%r13) | 	larl	%r13,.Lpgm_new_psw | ||||||
| 	mvc	__LC_PGM_NEW_PSW(16),.Lpgm_new_psw-.LPG0(%r13) | 	mvc	__LC_PGM_NEW_PSW(16),0(%r13) | ||||||
| 	mvc	__LC_IO_NEW_PSW(16),.Lio_new_psw-.LPG0(%r13) | 	larl	%r13,.Lio_new_psw | ||||||
|  | 	mvc	__LC_IO_NEW_PSW(16),0(%r13) | ||||||
| 	xc	0x200(256),0x200	# partially clear lowcore | 	xc	0x200(256),0x200	# partially clear lowcore | ||||||
| 	xc	0x300(256),0x300 | 	xc	0x300(256),0x300 | ||||||
| 	xc	0xe00(256),0xe00 | 	xc	0xe00(256),0xe00 | ||||||
| 	xc	0xf00(256),0xf00 | 	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 | 	stcke	__LC_BOOT_CLOCK | ||||||
| 	mvc	__LC_LAST_UPDATE_CLOCK(8),__LC_BOOT_CLOCK+1 | 	mvc	__LC_LAST_UPDATE_CLOCK(8),__LC_BOOT_CLOCK+1 | ||||||
| 	spt	6f-.LPG0(%r13) | 	larl	%r13,6f | ||||||
| 	mvc	__LC_LAST_UPDATE_TIMER(8),6f-.LPG0(%r13) | 	spt	0(%r13) | ||||||
|  | 	mvc	__LC_LAST_UPDATE_TIMER(8),0(%r13) | ||||||
| 	larl	%r15,_stack_end-STACK_FRAME_OVERHEAD | 	larl	%r15,_stack_end-STACK_FRAME_OVERHEAD | ||||||
| 	brasl	%r14,sclp_early_setup_buffer | 	brasl	%r14,sclp_early_setup_buffer | ||||||
| 	brasl	%r14,verify_facilities | 	brasl	%r14,verify_facilities | ||||||
|  |  | ||||||
		Loading…
	
		Reference in a new issue
	
	 Heiko Carstens
						Heiko Carstens