Skip to content

Commit 691632f

Browse files
committed
Merge tag 's390-6.9-1' of git://git.kernel.org/pub/scm/linux/kernel/git/s390/linux
Pull s390 updates from Heiko Carstens: - Various virtual vs physical address usage fixes - Fix error handling in Processor Activity Instrumentation device driver, and export number of counters with a sysfs file - Allow for multiple events when Processor Activity Instrumentation counters are monitored in system wide sampling - Change multiplier and shift values of the Time-of-Day clock source to improve steering precision - Remove a couple of unneeded GFP_DMA flags from allocations - Disable mmap alignment if randomize_va_space is also disabled, to avoid a too small heap - Various changes to allow s390 to be compiled with LLVM=1, since ld.lld and llvm-objcopy will have proper s390 support witch clang 19 - Add __uninitialized macro to Compiler Attributes. This is helpful with s390's FPU code where some users have up to 520 byte stack frames. Clearing such stack frames (if INIT_STACK_ALL_PATTERN or INIT_STACK_ALL_ZERO is enabled) before they are used contradicts the intention (performance improvement) of such code sections. - Convert switch_to() to an out-of-line function, and use the generic switch_to header file - Replace the usage of s390's debug feature with pr_debug() calls within the zcrypt device driver - Improve hotplug support of the Adjunct Processor device driver - Improve retry handling in the zcrypt device driver - Various changes to the in-kernel FPU code: - Make in-kernel FPU sections preemptible - Convert various larger inline assemblies and assembler files to C, mainly by using singe instruction inline assemblies. This increases readability, but also allows makes it easier to add proper instrumentation hooks - Cleanup of the header files - Provide fast variants of csum_partial() and csum_partial_copy_nocheck() based on vector instructions - Introduce and use a lock to synchronize accesses to zpci device data structures to avoid inconsistent states caused by concurrent accesses - Compile the kernel without -fPIE. This addresses the following problems if the kernel is compiled with -fPIE: - It uses dynamic symbols (.dynsym), for which the linker refuses to allow more than 64k sections. This can break features which use '-ffunction-sections' and '-fdata-sections', including kpatch-build and function granular KASLR - It unnecessarily uses GOT relocations, adding an extra layer of indirection for many memory accesses - Fix shared_cpu_list for CPU private L2 caches, which incorrectly were reported as globally shared * tag 's390-6.9-1' of git://git.kernel.org/pub/scm/linux/kernel/git/s390/linux: (117 commits) s390/tools: handle rela R_390_GOTPCDBL/R_390_GOTOFF64 s390/cache: prevent rebuild of shared_cpu_list s390/crypto: remove retry loop with sleep from PAES pkey invocation s390/pkey: improve pkey retry behavior s390/zcrypt: improve zcrypt retry behavior s390/zcrypt: introduce retries on in-kernel send CPRB functions s390/ap: introduce mutex to lock the AP bus scan s390/ap: rework ap_scan_bus() to return true on config change s390/ap: clarify AP scan bus related functions and variables s390/ap: rearm APQNs bindings complete completion s390/configs: increase number of LOCKDEP_BITS s390/vfio-ap: handle hardware checkstop state on queue reset operation s390/pai: change sampling event assignment for PMU device driver s390/boot: fix minor comment style damages s390/boot: do not check for zero-termination relocation entry s390/boot: make type of __vmlinux_relocs_64_start|end consistent s390/boot: sanitize kaslr_adjust_relocs() function prototype s390/boot: simplify GOT handling s390: vmlinux.lds.S: fix .got.plt assertion s390/boot: workaround current 'llvm-objdump -t -j ...' behavior ...
2 parents b29f377 + fa9e313 commit 691632f

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

115 files changed

+3246
-1916
lines changed

arch/s390/Kconfig

Lines changed: 14 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -127,6 +127,7 @@ config S390
127127
select ARCH_WANT_DEFAULT_BPF_JIT
128128
select ARCH_WANT_IPC_PARSE_VERSION
129129
select ARCH_WANT_KERNEL_PMD_MKWRITE
130+
select ARCH_WANT_LD_ORPHAN_WARN
130131
select ARCH_WANT_OPTIMIZE_HUGETLB_VMEMMAP
131132
select BUILDTIME_TABLE_SORT
132133
select CLONE_BACKWARDS2
@@ -448,7 +449,7 @@ config COMPAT
448449
select COMPAT_OLD_SIGACTION
449450
select HAVE_UID16
450451
depends on MULTIUSER
451-
depends on !CC_IS_CLANG
452+
depends on !CC_IS_CLANG && !LD_IS_LLD
452453
help
453454
Select this option if you want to enable your system kernel to
454455
handle system-calls from ELF binaries for 31 bit ESA. This option
@@ -582,14 +583,23 @@ config RELOCATABLE
582583
help
583584
This builds a kernel image that retains relocation information
584585
so it can be loaded at an arbitrary address.
585-
The kernel is linked as a position-independent executable (PIE)
586-
and contains dynamic relocations which are processed early in the
587-
bootup process.
588586
The relocations make the kernel image about 15% larger (compressed
589587
10%), but are discarded at runtime.
590588
Note: this option exists only for documentation purposes, please do
591589
not remove it.
592590

591+
config PIE_BUILD
592+
def_bool CC_IS_CLANG && !$(cc-option,-munaligned-symbols)
593+
help
594+
If the compiler is unable to generate code that can manage unaligned
595+
symbols, the kernel is linked as a position-independent executable
596+
(PIE) and includes dynamic relocations that are processed early
597+
during bootup.
598+
599+
For kpatch functionality, it is recommended to build the kernel
600+
without the PIE_BUILD option. PIE_BUILD is only enabled when the
601+
compiler lacks proper support for handling unaligned symbols.
602+
593603
config RANDOMIZE_BASE
594604
bool "Randomize the address of the kernel image (KASLR)"
595605
default y

arch/s390/Makefile

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -14,8 +14,14 @@ KBUILD_AFLAGS_MODULE += -fPIC
1414
KBUILD_CFLAGS_MODULE += -fPIC
1515
KBUILD_AFLAGS += -m64
1616
KBUILD_CFLAGS += -m64
17+
ifdef CONFIG_PIE_BUILD
1718
KBUILD_CFLAGS += -fPIE
18-
LDFLAGS_vmlinux := -pie
19+
LDFLAGS_vmlinux := -pie -z notext
20+
else
21+
KBUILD_CFLAGS += $(call cc-option,-munaligned-symbols,)
22+
LDFLAGS_vmlinux := --emit-relocs --discard-none
23+
extra_tools := relocs
24+
endif
1925
aflags_dwarf := -Wa,-gdwarf-2
2026
KBUILD_AFLAGS_DECOMPRESSOR := $(CLANG_FLAGS) -m64 -D__ASSEMBLY__
2127
ifndef CONFIG_AS_IS_LLVM
@@ -143,7 +149,7 @@ archheaders:
143149

144150
archprepare:
145151
$(Q)$(MAKE) $(build)=$(syscalls) kapi
146-
$(Q)$(MAKE) $(build)=$(tools) kapi
152+
$(Q)$(MAKE) $(build)=$(tools) kapi $(extra_tools)
147153
ifeq ($(KBUILD_EXTMOD),)
148154
# We need to generate vdso-offsets.h before compiling certain files in kernel/.
149155
# In order to do that, we should use the archprepare target, but we can't since

arch/s390/boot/.gitignore

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
# SPDX-License-Identifier: GPL-2.0-only
22
image
33
bzImage
4+
relocs.S
45
section_cmp.*
56
vmlinux
67
vmlinux.lds

arch/s390/boot/Makefile

Lines changed: 19 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -37,7 +37,8 @@ CFLAGS_sclp_early_core.o += -I$(srctree)/drivers/s390/char
3737

3838
obj-y := head.o als.o startup.o physmem_info.o ipl_parm.o ipl_report.o vmem.o
3939
obj-y += string.o ebcdic.o sclp_early_core.o mem.o ipl_vmparm.o cmdline.o
40-
obj-y += version.o pgm_check_info.o ctype.o ipl_data.o machine_kexec_reloc.o
40+
obj-y += version.o pgm_check_info.o ctype.o ipl_data.o
41+
obj-y += $(if $(CONFIG_PIE_BUILD),machine_kexec_reloc.o,relocs.o)
4142
obj-$(findstring y, $(CONFIG_PROTECTED_VIRTUALIZATION_GUEST) $(CONFIG_PGSTE)) += uv.o
4243
obj-$(CONFIG_RANDOMIZE_BASE) += kaslr.o
4344
obj-y += $(if $(CONFIG_KERNEL_UNCOMPRESSED),,decompressor.o) info.o
@@ -48,6 +49,9 @@ targets := bzImage section_cmp.boot.data section_cmp.boot.preserved.data $(obj-y
4849
targets += vmlinux.lds vmlinux vmlinux.bin vmlinux.bin.gz vmlinux.bin.bz2
4950
targets += vmlinux.bin.xz vmlinux.bin.lzma vmlinux.bin.lzo vmlinux.bin.lz4
5051
targets += vmlinux.bin.zst info.bin syms.bin vmlinux.syms $(obj-all)
52+
ifndef CONFIG_PIE_BUILD
53+
targets += relocs.S
54+
endif
5155

5256
OBJECTS := $(addprefix $(obj)/,$(obj-y))
5357
OBJECTS_ALL := $(addprefix $(obj)/,$(obj-all))
@@ -56,9 +60,9 @@ clean-files += vmlinux.map
5660

5761
quiet_cmd_section_cmp = SECTCMP $*
5862
define cmd_section_cmp
59-
s1=`$(OBJDUMP) -t -j "$*" "$<" | sort | \
63+
s1=`$(OBJDUMP) -t "$<" | grep "\s$*\s\+" | sort | \
6064
sed -n "/0000000000000000/! s/.*\s$*\s\+//p" | sha256sum`; \
61-
s2=`$(OBJDUMP) -t -j "$*" "$(word 2,$^)" | sort | \
65+
s2=`$(OBJDUMP) -t "$(word 2,$^)" | grep "\s$*\s\+" | sort | \
6266
sed -n "/0000000000000000/! s/.*\s$*\s\+//p" | sha256sum`; \
6367
if [ "$$s1" != "$$s2" ]; then \
6468
echo "error: section $* differs between $< and $(word 2,$^)" >&2; \
@@ -73,11 +77,12 @@ $(obj)/bzImage: $(obj)/vmlinux $(obj)/section_cmp.boot.data $(obj)/section_cmp.b
7377
$(obj)/section_cmp%: vmlinux $(obj)/vmlinux FORCE
7478
$(call if_changed,section_cmp)
7579

76-
LDFLAGS_vmlinux := --oformat $(LD_BFD) -e startup $(if $(CONFIG_VMLINUX_MAP),-Map=$(obj)/vmlinux.map) --build-id=sha1 -T
80+
LDFLAGS_vmlinux-$(CONFIG_LD_ORPHAN_WARN) := --orphan-handling=$(CONFIG_LD_ORPHAN_WARN_LEVEL)
81+
LDFLAGS_vmlinux := $(LDFLAGS_vmlinux-y) --oformat $(LD_BFD) -e startup $(if $(CONFIG_VMLINUX_MAP),-Map=$(obj)/vmlinux.map) --build-id=sha1 -T
7782
$(obj)/vmlinux: $(obj)/vmlinux.lds $(OBJECTS_ALL) FORCE
7883
$(call if_changed,ld)
7984

80-
LDFLAGS_vmlinux.syms := --oformat $(LD_BFD) -e startup -T
85+
LDFLAGS_vmlinux.syms := $(LDFLAGS_vmlinux-y) --oformat $(LD_BFD) -e startup -T
8186
$(obj)/vmlinux.syms: $(obj)/vmlinux.lds $(OBJECTS) FORCE
8287
$(call if_changed,ld)
8388

@@ -93,7 +98,7 @@ OBJCOPYFLAGS_syms.o := -I binary -O elf64-s390 -B s390:64-bit --rename-section .
9398
$(obj)/syms.o: $(obj)/syms.bin FORCE
9499
$(call if_changed,objcopy)
95100

96-
OBJCOPYFLAGS_info.bin := -O binary --only-section=.vmlinux.info --set-section-flags .vmlinux.info=load
101+
OBJCOPYFLAGS_info.bin := -O binary --only-section=.vmlinux.info --set-section-flags .vmlinux.info=alloc,load
97102
$(obj)/info.bin: vmlinux FORCE
98103
$(call if_changed,objcopy)
99104

@@ -105,6 +110,14 @@ OBJCOPYFLAGS_vmlinux.bin := -O binary --remove-section=.comment --remove-section
105110
$(obj)/vmlinux.bin: vmlinux FORCE
106111
$(call if_changed,objcopy)
107112

113+
ifndef CONFIG_PIE_BUILD
114+
CMD_RELOCS=arch/s390/tools/relocs
115+
quiet_cmd_relocs = RELOCS $@
116+
cmd_relocs = $(CMD_RELOCS) $< > $@
117+
$(obj)/relocs.S: vmlinux FORCE
118+
$(call if_changed,relocs)
119+
endif
120+
108121
suffix-$(CONFIG_KERNEL_GZIP) := .gz
109122
suffix-$(CONFIG_KERNEL_BZIP2) := .bz2
110123
suffix-$(CONFIG_KERNEL_LZ4) := .lz4

arch/s390/boot/boot.h

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -25,9 +25,14 @@ struct vmlinux_info {
2525
unsigned long bootdata_size;
2626
unsigned long bootdata_preserved_off;
2727
unsigned long bootdata_preserved_size;
28+
#ifdef CONFIG_PIE_BUILD
2829
unsigned long dynsym_start;
2930
unsigned long rela_dyn_start;
3031
unsigned long rela_dyn_end;
32+
#else
33+
unsigned long got_start;
34+
unsigned long got_end;
35+
#endif
3136
unsigned long amode31_size;
3237
unsigned long init_mm_off;
3338
unsigned long swapper_pg_dir_off;
@@ -83,6 +88,7 @@ extern unsigned long vmalloc_size;
8388
extern int vmalloc_size_set;
8489
extern char __boot_data_start[], __boot_data_end[];
8590
extern char __boot_data_preserved_start[], __boot_data_preserved_end[];
91+
extern char __vmlinux_relocs_64_start[], __vmlinux_relocs_64_end[];
8692
extern char _decompressor_syms_start[], _decompressor_syms_end[];
8793
extern char _stack_start[], _stack_end[];
8894
extern char _end[], _decompressor_end[];

arch/s390/boot/startup.c

Lines changed: 66 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -141,7 +141,8 @@ static void copy_bootdata(void)
141141
memcpy((void *)vmlinux.bootdata_preserved_off, __boot_data_preserved_start, vmlinux.bootdata_preserved_size);
142142
}
143143

144-
static void handle_relocs(unsigned long offset)
144+
#ifdef CONFIG_PIE_BUILD
145+
static void kaslr_adjust_relocs(unsigned long min_addr, unsigned long max_addr, unsigned long offset)
145146
{
146147
Elf64_Rela *rela_start, *rela_end, *rela;
147148
int r_type, r_sym, rc;
@@ -172,6 +173,54 @@ static void handle_relocs(unsigned long offset)
172173
}
173174
}
174175

176+
static void kaslr_adjust_got(unsigned long offset) {}
177+
static void rescue_relocs(void) {}
178+
static void free_relocs(void) {}
179+
#else
180+
static int *vmlinux_relocs_64_start;
181+
static int *vmlinux_relocs_64_end;
182+
183+
static void rescue_relocs(void)
184+
{
185+
unsigned long size = __vmlinux_relocs_64_end - __vmlinux_relocs_64_start;
186+
187+
vmlinux_relocs_64_start = (void *)physmem_alloc_top_down(RR_RELOC, size, 0);
188+
vmlinux_relocs_64_end = (void *)vmlinux_relocs_64_start + size;
189+
memmove(vmlinux_relocs_64_start, __vmlinux_relocs_64_start, size);
190+
}
191+
192+
static void free_relocs(void)
193+
{
194+
physmem_free(RR_RELOC);
195+
}
196+
197+
static void kaslr_adjust_relocs(unsigned long min_addr, unsigned long max_addr, unsigned long offset)
198+
{
199+
int *reloc;
200+
long loc;
201+
202+
/* Adjust R_390_64 relocations */
203+
for (reloc = vmlinux_relocs_64_start; reloc < vmlinux_relocs_64_end; reloc++) {
204+
loc = (long)*reloc + offset;
205+
if (loc < min_addr || loc > max_addr)
206+
error("64-bit relocation outside of kernel!\n");
207+
*(u64 *)loc += offset;
208+
}
209+
}
210+
211+
static void kaslr_adjust_got(unsigned long offset)
212+
{
213+
u64 *entry;
214+
215+
/*
216+
* Even without -fPIE, Clang still uses a global offset table for some
217+
* reason. Adjust the GOT entries.
218+
*/
219+
for (entry = (u64 *)vmlinux.got_start; entry < (u64 *)vmlinux.got_end; entry++)
220+
*entry += offset;
221+
}
222+
#endif
223+
175224
/*
176225
* Merge information from several sources into a single ident_map_size value.
177226
* "ident_map_size" represents the upper limit of physical memory we may ever
@@ -299,14 +348,19 @@ static void setup_vmalloc_size(void)
299348
vmalloc_size = max(size, vmalloc_size);
300349
}
301350

302-
static void offset_vmlinux_info(unsigned long offset)
351+
static void kaslr_adjust_vmlinux_info(unsigned long offset)
303352
{
304353
*(unsigned long *)(&vmlinux.entry) += offset;
305354
vmlinux.bootdata_off += offset;
306355
vmlinux.bootdata_preserved_off += offset;
356+
#ifdef CONFIG_PIE_BUILD
307357
vmlinux.rela_dyn_start += offset;
308358
vmlinux.rela_dyn_end += offset;
309359
vmlinux.dynsym_start += offset;
360+
#else
361+
vmlinux.got_start += offset;
362+
vmlinux.got_end += offset;
363+
#endif
310364
vmlinux.init_mm_off += offset;
311365
vmlinux.swapper_pg_dir_off += offset;
312366
vmlinux.invalid_pg_dir_off += offset;
@@ -361,14 +415,15 @@ void startup_kernel(void)
361415
detect_physmem_online_ranges(max_physmem_end);
362416
save_ipl_cert_comp_list();
363417
rescue_initrd(safe_addr, ident_map_size);
418+
rescue_relocs();
364419

365420
if (kaslr_enabled()) {
366421
vmlinux_lma = randomize_within_range(vmlinux.image_size + vmlinux.bss_size,
367422
THREAD_SIZE, vmlinux.default_lma,
368423
ident_map_size);
369424
if (vmlinux_lma) {
370425
__kaslr_offset = vmlinux_lma - vmlinux.default_lma;
371-
offset_vmlinux_info(__kaslr_offset);
426+
kaslr_adjust_vmlinux_info(__kaslr_offset);
372427
}
373428
}
374429
vmlinux_lma = vmlinux_lma ?: vmlinux.default_lma;
@@ -393,18 +448,20 @@ void startup_kernel(void)
393448
/*
394449
* The order of the following operations is important:
395450
*
396-
* - handle_relocs() must follow clear_bss_section() to establish static
397-
* memory references to data in .bss to be used by setup_vmem()
451+
* - kaslr_adjust_relocs() must follow clear_bss_section() to establish
452+
* static memory references to data in .bss to be used by setup_vmem()
398453
* (i.e init_mm.pgd)
399454
*
400-
* - setup_vmem() must follow handle_relocs() to be able using
455+
* - setup_vmem() must follow kaslr_adjust_relocs() to be able using
401456
* static memory references to data in .bss (i.e init_mm.pgd)
402457
*
403-
* - copy_bootdata() must follow setup_vmem() to propagate changes to
404-
* bootdata made by setup_vmem()
458+
* - copy_bootdata() must follow setup_vmem() to propagate changes
459+
* to bootdata made by setup_vmem()
405460
*/
406461
clear_bss_section(vmlinux_lma);
407-
handle_relocs(__kaslr_offset);
462+
kaslr_adjust_relocs(vmlinux_lma, vmlinux_lma + vmlinux.image_size, __kaslr_offset);
463+
kaslr_adjust_got(__kaslr_offset);
464+
free_relocs();
408465
setup_vmem(asce_limit);
409466
copy_bootdata();
410467

arch/s390/boot/vmlinux.lds.S

Lines changed: 48 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,7 @@ SECTIONS
3131
_text = .; /* Text */
3232
*(.text)
3333
*(.text.*)
34+
INIT_TEXT
3435
_etext = . ;
3536
}
3637
.rodata : {
@@ -39,6 +40,9 @@ SECTIONS
3940
*(.rodata.*)
4041
_erodata = . ;
4142
}
43+
.got : {
44+
*(.got)
45+
}
4246
NOTES
4347
.data : {
4448
_data = . ;
@@ -106,6 +110,24 @@ SECTIONS
106110
_compressed_end = .;
107111
}
108112

113+
#ifndef CONFIG_PIE_BUILD
114+
/*
115+
* When the kernel is built with CONFIG_KERNEL_UNCOMPRESSED, the entire
116+
* uncompressed vmlinux.bin is positioned in the bzImage decompressor
117+
* image at the default kernel LMA of 0x100000, enabling it to be
118+
* executed in-place. However, the size of .vmlinux.relocs could be
119+
* large enough to cause an overlap with the uncompressed kernel at the
120+
* address 0x100000. To address this issue, .vmlinux.relocs is
121+
* positioned after the .rodata.compressed.
122+
*/
123+
. = ALIGN(4);
124+
.vmlinux.relocs : {
125+
__vmlinux_relocs_64_start = .;
126+
*(.vmlinux.relocs_64)
127+
__vmlinux_relocs_64_end = .;
128+
}
129+
#endif
130+
109131
#define SB_TRAILER_SIZE 32
110132
/* Trailer needed for Secure Boot */
111133
. += SB_TRAILER_SIZE; /* make sure .sb.trailer does not overwrite the previous section */
@@ -118,8 +140,34 @@ SECTIONS
118140
}
119141
_end = .;
120142

143+
DWARF_DEBUG
144+
ELF_DETAILS
145+
146+
/*
147+
* Make sure that the .got.plt is either completely empty or it
148+
* contains only the three reserved double words.
149+
*/
150+
.got.plt : {
151+
*(.got.plt)
152+
}
153+
ASSERT(SIZEOF(.got.plt) == 0 || SIZEOF(.got.plt) == 0x18, "Unexpected GOT/PLT entries detected!")
154+
155+
/*
156+
* Sections that should stay zero sized, which is safer to
157+
* explicitly check instead of blindly discarding.
158+
*/
159+
.plt : {
160+
*(.plt) *(.plt.*) *(.iplt) *(.igot .igot.plt)
161+
}
162+
ASSERT(SIZEOF(.plt) == 0, "Unexpected run-time procedure linkages detected!")
163+
.rela.dyn : {
164+
*(.rela.*) *(.rela_*)
165+
}
166+
ASSERT(SIZEOF(.rela.dyn) == 0, "Unexpected run-time relocations (.rela) detected!")
167+
121168
/* Sections to be discarded */
122169
/DISCARD/ : {
170+
COMMON_DISCARDS
123171
*(.eh_frame)
124172
*(__ex_table)
125173
*(*__ksymtab*)

arch/s390/configs/debug_defconfig

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -824,6 +824,8 @@ CONFIG_TEST_LOCKUP=m
824824
CONFIG_DEBUG_PREEMPT=y
825825
CONFIG_PROVE_LOCKING=y
826826
CONFIG_LOCK_STAT=y
827+
CONFIG_LOCKDEP_BITS=16
828+
CONFIG_LOCKDEP_CHAINS_BITS=17
827829
CONFIG_DEBUG_ATOMIC_SLEEP=y
828830
CONFIG_DEBUG_LOCKING_API_SELFTESTS=y
829831
CONFIG_DEBUG_IRQFLAGS=y

0 commit comments

Comments
 (0)