Skip to content

Commit 66242ef

Browse files
committed
Merge tag 's390-6.11-3' of git://git.kernel.org/pub/scm/linux/kernel/git/s390/linux
Pull s390 fixes from Vasily Gorbik: - remove unused empty CPU alternatives header file - fix recently and erroneously removed exception handling when loading an invalid floating point register - ptdump fixes to reflect the recent changes due to the uncoupling of physical vs virtual kernel address spaces - changes to avoid the unnecessary splitting of large pages in kernel mappings - add the missing MODULE_DESCRIPTION for the CIO modules * tag 's390-6.11-3' of git://git.kernel.org/pub/scm/linux/kernel/git/s390/linux: s390: Keep inittext section writable s390/vmlinux.lds.S: Move ro_after_init section behind rodata section s390/mm: Get rid of RELOC_HIDE() s390/mm/ptdump: Improve sorting of markers s390/mm/ptdump: Add support for relocated lowcore mapping s390/mm/ptdump: Fix handling of identity mapping area s390/cio: Add missing MODULE_DESCRIPTION() macros s390/alternatives: Remove unused empty header file s390/fpu: Re-add exception handling in load_fpu_state()
2 parents 29ccb40 + 33bd8d1 commit 66242ef

File tree

8 files changed

+95
-88
lines changed

8 files changed

+95
-88
lines changed

arch/s390/kernel/alternative.h

Whitespace-only changes.

arch/s390/kernel/fpu.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -113,7 +113,7 @@ void load_fpu_state(struct fpu *state, int flags)
113113
int mask;
114114

115115
if (flags & KERNEL_FPC)
116-
fpu_lfpc(&state->fpc);
116+
fpu_lfpc_safe(&state->fpc);
117117
if (!cpu_has_vx()) {
118118
if (flags & KERNEL_VXR_V0V7)
119119
load_fp_regs_vx(state->vxrs);

arch/s390/kernel/vmlinux.lds.S

Lines changed: 9 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -59,14 +59,6 @@ SECTIONS
5959
} :text = 0x0700
6060

6161
RO_DATA(PAGE_SIZE)
62-
.data.rel.ro : {
63-
*(.data.rel.ro .data.rel.ro.*)
64-
}
65-
.got : {
66-
__got_start = .;
67-
*(.got)
68-
__got_end = .;
69-
}
7062

7163
. = ALIGN(PAGE_SIZE);
7264
_sdata = .; /* Start of data section */
@@ -80,6 +72,15 @@ SECTIONS
8072
. = ALIGN(PAGE_SIZE);
8173
__end_ro_after_init = .;
8274

75+
.data.rel.ro : {
76+
*(.data.rel.ro .data.rel.ro.*)
77+
}
78+
.got : {
79+
__got_start = .;
80+
*(.got)
81+
__got_end = .;
82+
}
83+
8384
RW_DATA(0x100, PAGE_SIZE, THREAD_SIZE)
8485
.data.rel : {
8586
*(.data.rel*)

arch/s390/mm/dump_pagetables.c

Lines changed: 79 additions & 61 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@
33
#include <linux/ptdump.h>
44
#include <linux/seq_file.h>
55
#include <linux/debugfs.h>
6+
#include <linux/sort.h>
67
#include <linux/mm.h>
78
#include <linux/kfence.h>
89
#include <linux/kasan.h>
@@ -15,13 +16,15 @@
1516
static unsigned long max_addr;
1617

1718
struct addr_marker {
19+
int is_start;
1820
unsigned long start_address;
1921
const char *name;
2022
};
2123

2224
enum address_markers_idx {
23-
IDENTITY_BEFORE_NR = 0,
24-
IDENTITY_BEFORE_END_NR,
25+
KVA_NR = 0,
26+
LOWCORE_START_NR,
27+
LOWCORE_END_NR,
2528
AMODE31_START_NR,
2629
AMODE31_END_NR,
2730
KERNEL_START_NR,
@@ -30,8 +33,8 @@ enum address_markers_idx {
3033
KFENCE_START_NR,
3134
KFENCE_END_NR,
3235
#endif
33-
IDENTITY_AFTER_NR,
34-
IDENTITY_AFTER_END_NR,
36+
IDENTITY_START_NR,
37+
IDENTITY_END_NR,
3538
VMEMMAP_NR,
3639
VMEMMAP_END_NR,
3740
VMALLOC_NR,
@@ -59,43 +62,44 @@ enum address_markers_idx {
5962
};
6063

6164
static struct addr_marker address_markers[] = {
62-
[IDENTITY_BEFORE_NR] = {0, "Identity Mapping Start"},
63-
[IDENTITY_BEFORE_END_NR] = {(unsigned long)_stext, "Identity Mapping End"},
64-
[AMODE31_START_NR] = {0, "Amode31 Area Start"},
65-
[AMODE31_END_NR] = {0, "Amode31 Area End"},
66-
[KERNEL_START_NR] = {(unsigned long)_stext, "Kernel Image Start"},
67-
[KERNEL_END_NR] = {(unsigned long)_end, "Kernel Image End"},
65+
[KVA_NR] = {0, 0, "Kernel Virtual Address Space"},
66+
[LOWCORE_START_NR] = {1, 0, "Lowcore Start"},
67+
[LOWCORE_END_NR] = {0, 0, "Lowcore End"},
68+
[IDENTITY_START_NR] = {1, 0, "Identity Mapping Start"},
69+
[IDENTITY_END_NR] = {0, 0, "Identity Mapping End"},
70+
[AMODE31_START_NR] = {1, 0, "Amode31 Area Start"},
71+
[AMODE31_END_NR] = {0, 0, "Amode31 Area End"},
72+
[KERNEL_START_NR] = {1, (unsigned long)_stext, "Kernel Image Start"},
73+
[KERNEL_END_NR] = {0, (unsigned long)_end, "Kernel Image End"},
6874
#ifdef CONFIG_KFENCE
69-
[KFENCE_START_NR] = {0, "KFence Pool Start"},
70-
[KFENCE_END_NR] = {0, "KFence Pool End"},
75+
[KFENCE_START_NR] = {1, 0, "KFence Pool Start"},
76+
[KFENCE_END_NR] = {0, 0, "KFence Pool End"},
7177
#endif
72-
[IDENTITY_AFTER_NR] = {(unsigned long)_end, "Identity Mapping Start"},
73-
[IDENTITY_AFTER_END_NR] = {0, "Identity Mapping End"},
74-
[VMEMMAP_NR] = {0, "vmemmap Area Start"},
75-
[VMEMMAP_END_NR] = {0, "vmemmap Area End"},
76-
[VMALLOC_NR] = {0, "vmalloc Area Start"},
77-
[VMALLOC_END_NR] = {0, "vmalloc Area End"},
78+
[VMEMMAP_NR] = {1, 0, "vmemmap Area Start"},
79+
[VMEMMAP_END_NR] = {0, 0, "vmemmap Area End"},
80+
[VMALLOC_NR] = {1, 0, "vmalloc Area Start"},
81+
[VMALLOC_END_NR] = {0, 0, "vmalloc Area End"},
7882
#ifdef CONFIG_KMSAN
79-
[KMSAN_VMALLOC_SHADOW_START_NR] = {0, "Kmsan vmalloc Shadow Start"},
80-
[KMSAN_VMALLOC_SHADOW_END_NR] = {0, "Kmsan vmalloc Shadow End"},
81-
[KMSAN_VMALLOC_ORIGIN_START_NR] = {0, "Kmsan vmalloc Origins Start"},
82-
[KMSAN_VMALLOC_ORIGIN_END_NR] = {0, "Kmsan vmalloc Origins End"},
83-
[KMSAN_MODULES_SHADOW_START_NR] = {0, "Kmsan Modules Shadow Start"},
84-
[KMSAN_MODULES_SHADOW_END_NR] = {0, "Kmsan Modules Shadow End"},
85-
[KMSAN_MODULES_ORIGIN_START_NR] = {0, "Kmsan Modules Origins Start"},
86-
[KMSAN_MODULES_ORIGIN_END_NR] = {0, "Kmsan Modules Origins End"},
83+
[KMSAN_VMALLOC_SHADOW_START_NR] = {1, 0, "Kmsan vmalloc Shadow Start"},
84+
[KMSAN_VMALLOC_SHADOW_END_NR] = {0, 0, "Kmsan vmalloc Shadow End"},
85+
[KMSAN_VMALLOC_ORIGIN_START_NR] = {1, 0, "Kmsan vmalloc Origins Start"},
86+
[KMSAN_VMALLOC_ORIGIN_END_NR] = {0, 0, "Kmsan vmalloc Origins End"},
87+
[KMSAN_MODULES_SHADOW_START_NR] = {1, 0, "Kmsan Modules Shadow Start"},
88+
[KMSAN_MODULES_SHADOW_END_NR] = {0, 0, "Kmsan Modules Shadow End"},
89+
[KMSAN_MODULES_ORIGIN_START_NR] = {1, 0, "Kmsan Modules Origins Start"},
90+
[KMSAN_MODULES_ORIGIN_END_NR] = {0, 0, "Kmsan Modules Origins End"},
8791
#endif
88-
[MODULES_NR] = {0, "Modules Area Start"},
89-
[MODULES_END_NR] = {0, "Modules Area End"},
90-
[ABS_LOWCORE_NR] = {0, "Lowcore Area Start"},
91-
[ABS_LOWCORE_END_NR] = {0, "Lowcore Area End"},
92-
[MEMCPY_REAL_NR] = {0, "Real Memory Copy Area Start"},
93-
[MEMCPY_REAL_END_NR] = {0, "Real Memory Copy Area End"},
92+
[MODULES_NR] = {1, 0, "Modules Area Start"},
93+
[MODULES_END_NR] = {0, 0, "Modules Area End"},
94+
[ABS_LOWCORE_NR] = {1, 0, "Lowcore Area Start"},
95+
[ABS_LOWCORE_END_NR] = {0, 0, "Lowcore Area End"},
96+
[MEMCPY_REAL_NR] = {1, 0, "Real Memory Copy Area Start"},
97+
[MEMCPY_REAL_END_NR] = {0, 0, "Real Memory Copy Area End"},
9498
#ifdef CONFIG_KASAN
95-
[KASAN_SHADOW_START_NR] = {KASAN_SHADOW_START, "Kasan Shadow Start"},
96-
[KASAN_SHADOW_END_NR] = {KASAN_SHADOW_END, "Kasan Shadow End"},
99+
[KASAN_SHADOW_START_NR] = {1, KASAN_SHADOW_START, "Kasan Shadow Start"},
100+
[KASAN_SHADOW_END_NR] = {0, KASAN_SHADOW_END, "Kasan Shadow End"},
97101
#endif
98-
{ -1, NULL }
102+
{1, -1UL, NULL}
99103
};
100104

101105
struct pg_state {
@@ -163,6 +167,19 @@ static void note_prot_wx(struct pg_state *st, unsigned long addr)
163167
st->wx_pages += (addr - st->start_address) / PAGE_SIZE;
164168
}
165169

170+
static void note_page_update_state(struct pg_state *st, unsigned long addr, unsigned int prot, int level)
171+
{
172+
struct seq_file *m = st->seq;
173+
174+
while (addr >= st->marker[1].start_address) {
175+
st->marker++;
176+
pt_dump_seq_printf(m, "---[ %s ]---\n", st->marker->name);
177+
}
178+
st->start_address = addr;
179+
st->current_prot = prot;
180+
st->level = level;
181+
}
182+
166183
static void note_page(struct ptdump_state *pt_st, unsigned long addr, int level, u64 val)
167184
{
168185
int width = sizeof(unsigned long) * 2;
@@ -186,9 +203,7 @@ static void note_page(struct ptdump_state *pt_st, unsigned long addr, int level,
186203
addr = max_addr;
187204
if (st->level == -1) {
188205
pt_dump_seq_printf(m, "---[ %s ]---\n", st->marker->name);
189-
st->start_address = addr;
190-
st->current_prot = prot;
191-
st->level = level;
206+
note_page_update_state(st, addr, prot, level);
192207
} else if (prot != st->current_prot || level != st->level ||
193208
addr >= st->marker[1].start_address) {
194209
note_prot_wx(st, addr);
@@ -202,13 +217,7 @@ static void note_page(struct ptdump_state *pt_st, unsigned long addr, int level,
202217
}
203218
pt_dump_seq_printf(m, "%9lu%c ", delta, *unit);
204219
print_prot(m, st->current_prot, st->level);
205-
while (addr >= st->marker[1].start_address) {
206-
st->marker++;
207-
pt_dump_seq_printf(m, "---[ %s ]---\n", st->marker->name);
208-
}
209-
st->start_address = addr;
210-
st->current_prot = prot;
211-
st->level = level;
220+
note_page_update_state(st, addr, prot, level);
212221
}
213222
}
214223

@@ -280,37 +289,45 @@ static int ptdump_show(struct seq_file *m, void *v)
280289
DEFINE_SHOW_ATTRIBUTE(ptdump);
281290
#endif /* CONFIG_PTDUMP_DEBUGFS */
282291

283-
/*
284-
* Heapsort from lib/sort.c is not a stable sorting algorithm, do a simple
285-
* insertion sort to preserve the original order of markers with the same
286-
* start address.
287-
*/
288-
static void sort_address_markers(void)
292+
static int ptdump_cmp(const void *a, const void *b)
289293
{
290-
struct addr_marker tmp;
291-
int i, j;
294+
const struct addr_marker *ama = a;
295+
const struct addr_marker *amb = b;
292296

293-
for (i = 1; i < ARRAY_SIZE(address_markers) - 1; i++) {
294-
tmp = address_markers[i];
295-
for (j = i - 1; j >= 0 && address_markers[j].start_address > tmp.start_address; j--)
296-
address_markers[j + 1] = address_markers[j];
297-
address_markers[j + 1] = tmp;
298-
}
297+
if (ama->start_address > amb->start_address)
298+
return 1;
299+
if (ama->start_address < amb->start_address)
300+
return -1;
301+
/*
302+
* If the start addresses of two markers are identical consider the
303+
* marker which defines the start of an area higher than the one which
304+
* defines the end of an area. This keeps pairs of markers sorted.
305+
*/
306+
if (ama->is_start)
307+
return 1;
308+
if (amb->is_start)
309+
return -1;
310+
return 0;
299311
}
300312

301313
static int pt_dump_init(void)
302314
{
303315
#ifdef CONFIG_KFENCE
304316
unsigned long kfence_start = (unsigned long)__kfence_pool;
305317
#endif
318+
unsigned long lowcore = (unsigned long)get_lowcore();
319+
306320
/*
307321
* Figure out the maximum virtual address being accessible with the
308322
* kernel ASCE. We need this to keep the page table walker functions
309323
* from accessing non-existent entries.
310324
*/
311325
max_addr = (get_lowcore()->kernel_asce.val & _REGION_ENTRY_TYPE_MASK) >> 2;
312326
max_addr = 1UL << (max_addr * 11 + 31);
313-
address_markers[IDENTITY_AFTER_END_NR].start_address = ident_map_size;
327+
address_markers[LOWCORE_START_NR].start_address = lowcore;
328+
address_markers[LOWCORE_END_NR].start_address = lowcore + sizeof(struct lowcore);
329+
address_markers[IDENTITY_START_NR].start_address = __identity_base;
330+
address_markers[IDENTITY_END_NR].start_address = __identity_base + ident_map_size;
314331
address_markers[AMODE31_START_NR].start_address = (unsigned long)__samode31;
315332
address_markers[AMODE31_END_NR].start_address = (unsigned long)__eamode31;
316333
address_markers[MODULES_NR].start_address = MODULES_VADDR;
@@ -337,7 +354,8 @@ static int pt_dump_init(void)
337354
address_markers[KMSAN_MODULES_ORIGIN_START_NR].start_address = KMSAN_MODULES_ORIGIN_START;
338355
address_markers[KMSAN_MODULES_ORIGIN_END_NR].start_address = KMSAN_MODULES_ORIGIN_END;
339356
#endif
340-
sort_address_markers();
357+
sort(address_markers, ARRAY_SIZE(address_markers) - 1,
358+
sizeof(address_markers[0]), ptdump_cmp, NULL);
341359
#ifdef CONFIG_PTDUMP_DEBUGFS
342360
debugfs_create_file("kernel_page_tables", 0400, NULL, NULL, &ptdump_fops);
343361
#endif /* CONFIG_PTDUMP_DEBUGFS */

arch/s390/mm/init.c

Lines changed: 2 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -108,6 +108,8 @@ void mark_rodata_ro(void)
108108
{
109109
unsigned long size = __end_ro_after_init - __start_ro_after_init;
110110

111+
if (MACHINE_HAS_NX)
112+
system_ctl_set_bit(0, CR0_INSTRUCTION_EXEC_PROTECTION_BIT);
111113
__set_memory_ro(__start_ro_after_init, __end_ro_after_init);
112114
pr_info("Write protected read-only-after-init data: %luk\n", size >> 10);
113115
}
@@ -170,13 +172,6 @@ void __init mem_init(void)
170172
setup_zero_pages(); /* Setup zeroed pages. */
171173
}
172174

173-
void free_initmem(void)
174-
{
175-
set_memory_rwnx((unsigned long)_sinittext,
176-
(unsigned long)(_einittext - _sinittext) >> PAGE_SHIFT);
177-
free_initmem_default(POISON_FREE_INITMEM);
178-
}
179-
180175
unsigned long memory_block_size_bytes(void)
181176
{
182177
/*

arch/s390/mm/vmem.c

Lines changed: 2 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -661,7 +661,6 @@ void __init vmem_map_init(void)
661661
{
662662
__set_memory_rox(_stext, _etext);
663663
__set_memory_ro(_etext, __end_rodata);
664-
__set_memory_rox(_sinittext, _einittext);
665664
__set_memory_rox(__stext_amode31, __etext_amode31);
666665
/*
667666
* If the BEAR-enhancement facility is not installed the first
@@ -670,16 +669,8 @@ void __init vmem_map_init(void)
670669
*/
671670
if (!static_key_enabled(&cpu_has_bear))
672671
set_memory_x(0, 1);
673-
if (debug_pagealloc_enabled()) {
674-
/*
675-
* Use RELOC_HIDE() as long as __va(0) translates to NULL,
676-
* since performing pointer arithmetic on a NULL pointer
677-
* has undefined behavior and generates compiler warnings.
678-
*/
679-
__set_memory_4k(__va(0), RELOC_HIDE(__va(0), ident_map_size));
680-
}
681-
if (MACHINE_HAS_NX)
682-
system_ctl_set_bit(0, CR0_INSTRUCTION_EXEC_PROTECTION_BIT);
672+
if (debug_pagealloc_enabled())
673+
__set_memory_4k(__va(0), __va(0) + ident_map_size);
683674
pr_info("Write protected kernel read-only data: %luk\n",
684675
(unsigned long)(__end_rodata - _stext) >> 10);
685676
}

drivers/s390/cio/ccwgroup.c

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -550,4 +550,5 @@ void ccwgroup_remove_ccwdev(struct ccw_device *cdev)
550550
put_device(&gdev->dev);
551551
}
552552
EXPORT_SYMBOL(ccwgroup_remove_ccwdev);
553+
MODULE_DESCRIPTION("ccwgroup bus driver");
553554
MODULE_LICENSE("GPL");

drivers/s390/cio/vfio_ccw_drv.c

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -488,4 +488,5 @@ static void __exit vfio_ccw_sch_exit(void)
488488
module_init(vfio_ccw_sch_init);
489489
module_exit(vfio_ccw_sch_exit);
490490

491+
MODULE_DESCRIPTION("VFIO based Subchannel device driver");
491492
MODULE_LICENSE("GPL v2");

0 commit comments

Comments
 (0)