Skip to content

Commit 7e12284

Browse files
hcahcaVasily Gorbik
authored andcommitted
s390/mm/ptdump: Improve sorting of markers
Use the sort() from lib/sort.c to sort markers instead of the private implementation. The current implementation does not sort markers properly if they have to be moved downwards: ---[ Real Memory Copy Area Start ]--- 0x0000035b903ff000-0x0000035b90400000 4K PTE I ---[ vmalloc Area Start ]--- ---[ Real Memory Copy Area End ]--- Add a new member to each marker which indicates if a marker is start of an area. If addresses of areas are equal consider an address which defines the start of an area higher than the address which defines the end of an area. In result the output is sorted as intended: ---[ Real Memory Copy Area Start ]--- 0x0000019cedcff000-0x0000019cedd00000 4K PTE I ---[ Real Memory Copy Area End ]--- ---[ vmalloc Area Start ]--- Reviewed-by: Alexander Gordeev <[email protected]> Signed-off-by: Heiko Carstens <[email protected]> Signed-off-by: Vasily Gorbik <[email protected]>
1 parent 7e4d4cf commit 7e12284

File tree

1 file changed

+53
-47
lines changed

1 file changed

+53
-47
lines changed

arch/s390/mm/dump_pagetables.c

Lines changed: 53 additions & 47 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,6 +16,7 @@
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
};
@@ -60,44 +62,44 @@ enum address_markers_idx {
6062
};
6163

6264
static struct addr_marker address_markers[] = {
63-
[KVA_NR] = {0, "Kernel Virtual Address Space"},
64-
[LOWCORE_START_NR] = {0, "Lowcore Start"},
65-
[LOWCORE_END_NR] = {0, "Lowcore End"},
66-
[IDENTITY_START_NR] = {0, "Identity Mapping Start"},
67-
[IDENTITY_END_NR] = {0, "Identity Mapping End"},
68-
[AMODE31_START_NR] = {0, "Amode31 Area Start"},
69-
[AMODE31_END_NR] = {0, "Amode31 Area End"},
70-
[KERNEL_START_NR] = {(unsigned long)_stext, "Kernel Image Start"},
71-
[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"},
7274
#ifdef CONFIG_KFENCE
73-
[KFENCE_START_NR] = {0, "KFence Pool Start"},
74-
[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"},
7577
#endif
76-
[VMEMMAP_NR] = {0, "vmemmap Area Start"},
77-
[VMEMMAP_END_NR] = {0, "vmemmap Area End"},
78-
[VMALLOC_NR] = {0, "vmalloc Area Start"},
79-
[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"},
8082
#ifdef CONFIG_KMSAN
81-
[KMSAN_VMALLOC_SHADOW_START_NR] = {0, "Kmsan vmalloc Shadow Start"},
82-
[KMSAN_VMALLOC_SHADOW_END_NR] = {0, "Kmsan vmalloc Shadow End"},
83-
[KMSAN_VMALLOC_ORIGIN_START_NR] = {0, "Kmsan vmalloc Origins Start"},
84-
[KMSAN_VMALLOC_ORIGIN_END_NR] = {0, "Kmsan vmalloc Origins End"},
85-
[KMSAN_MODULES_SHADOW_START_NR] = {0, "Kmsan Modules Shadow Start"},
86-
[KMSAN_MODULES_SHADOW_END_NR] = {0, "Kmsan Modules Shadow End"},
87-
[KMSAN_MODULES_ORIGIN_START_NR] = {0, "Kmsan Modules Origins Start"},
88-
[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"},
8991
#endif
90-
[MODULES_NR] = {0, "Modules Area Start"},
91-
[MODULES_END_NR] = {0, "Modules Area End"},
92-
[ABS_LOWCORE_NR] = {0, "Lowcore Area Start"},
93-
[ABS_LOWCORE_END_NR] = {0, "Lowcore Area End"},
94-
[MEMCPY_REAL_NR] = {0, "Real Memory Copy Area Start"},
95-
[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"},
9698
#ifdef CONFIG_KASAN
97-
[KASAN_SHADOW_START_NR] = {KASAN_SHADOW_START, "Kasan Shadow Start"},
98-
[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"},
99101
#endif
100-
{ -1, NULL }
102+
{1, -1UL, NULL}
101103
};
102104

103105
struct pg_state {
@@ -287,22 +289,25 @@ static int ptdump_show(struct seq_file *m, void *v)
287289
DEFINE_SHOW_ATTRIBUTE(ptdump);
288290
#endif /* CONFIG_PTDUMP_DEBUGFS */
289291

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

300-
for (i = 1; i < ARRAY_SIZE(address_markers) - 1; i++) {
301-
tmp = address_markers[i];
302-
for (j = i - 1; j >= 0 && address_markers[j].start_address > tmp.start_address; j--)
303-
address_markers[j + 1] = address_markers[j];
304-
address_markers[j + 1] = tmp;
305-
}
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;
306311
}
307312

308313
static int pt_dump_init(void)
@@ -349,7 +354,8 @@ static int pt_dump_init(void)
349354
address_markers[KMSAN_MODULES_ORIGIN_START_NR].start_address = KMSAN_MODULES_ORIGIN_START;
350355
address_markers[KMSAN_MODULES_ORIGIN_END_NR].start_address = KMSAN_MODULES_ORIGIN_END;
351356
#endif
352-
sort_address_markers();
357+
sort(address_markers, ARRAY_SIZE(address_markers) - 1,
358+
sizeof(address_markers[0]), ptdump_cmp, NULL);
353359
#ifdef CONFIG_PTDUMP_DEBUGFS
354360
debugfs_create_file("kernel_page_tables", 0400, NULL, NULL, &ptdump_fops);
355361
#endif /* CONFIG_PTDUMP_DEBUGFS */

0 commit comments

Comments
 (0)