@@ -18,89 +18,12 @@ static unsigned long max_addr;
1818struct addr_marker {
1919 int is_start ;
2020 unsigned long start_address ;
21+ unsigned long size ;
2122 const char * name ;
2223};
2324
24- enum address_markers_idx {
25- KVA_NR = 0 ,
26- LOWCORE_START_NR ,
27- LOWCORE_END_NR ,
28- AMODE31_START_NR ,
29- AMODE31_END_NR ,
30- KERNEL_START_NR ,
31- KERNEL_END_NR ,
32- #ifdef CONFIG_KFENCE
33- KFENCE_START_NR ,
34- KFENCE_END_NR ,
35- #endif
36- IDENTITY_START_NR ,
37- IDENTITY_END_NR ,
38- VMEMMAP_NR ,
39- VMEMMAP_END_NR ,
40- VMALLOC_NR ,
41- VMALLOC_END_NR ,
42- #ifdef CONFIG_KMSAN
43- KMSAN_VMALLOC_SHADOW_START_NR ,
44- KMSAN_VMALLOC_SHADOW_END_NR ,
45- KMSAN_VMALLOC_ORIGIN_START_NR ,
46- KMSAN_VMALLOC_ORIGIN_END_NR ,
47- KMSAN_MODULES_SHADOW_START_NR ,
48- KMSAN_MODULES_SHADOW_END_NR ,
49- KMSAN_MODULES_ORIGIN_START_NR ,
50- KMSAN_MODULES_ORIGIN_END_NR ,
51- #endif
52- MODULES_NR ,
53- MODULES_END_NR ,
54- ABS_LOWCORE_NR ,
55- ABS_LOWCORE_END_NR ,
56- MEMCPY_REAL_NR ,
57- MEMCPY_REAL_END_NR ,
58- #ifdef CONFIG_KASAN
59- KASAN_SHADOW_START_NR ,
60- KASAN_SHADOW_END_NR ,
61- #endif
62- };
63-
64- static struct addr_marker address_markers [] = {
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" },
74- #ifdef CONFIG_KFENCE
75- [KFENCE_START_NR ] = {1 , 0 , "KFence Pool Start" },
76- [KFENCE_END_NR ] = {0 , 0 , "KFence Pool End" },
77- #endif
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" },
82- #ifdef CONFIG_KMSAN
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" },
91- #endif
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" },
98- #ifdef CONFIG_KASAN
99- [KASAN_SHADOW_START_NR ] = {1 , KASAN_SHADOW_START , "Kasan Shadow Start" },
100- [KASAN_SHADOW_END_NR ] = {0 , KASAN_SHADOW_END , "Kasan Shadow End" },
101- #endif
102- {1 , -1UL , NULL }
103- };
25+ static struct addr_marker * markers ;
26+ static unsigned int markers_cnt ;
10427
10528struct pg_state {
10629 struct ptdump_state ptdump ;
@@ -173,7 +96,8 @@ static void note_page_update_state(struct pg_state *st, unsigned long addr, unsi
17396
17497 while (addr >= st -> marker [1 ].start_address ) {
17598 st -> marker ++ ;
176- pt_dump_seq_printf (m , "---[ %s ]---\n" , st -> marker -> name );
99+ pt_dump_seq_printf (m , "---[ %s %s ]---\n" , st -> marker -> name ,
100+ st -> marker -> is_start ? "Start" : "End" );
177101 }
178102 st -> start_address = addr ;
179103 st -> current_prot = prot ;
@@ -202,7 +126,7 @@ static void note_page(struct ptdump_state *pt_st, unsigned long addr, int level,
202126 if (level == -1 )
203127 addr = max_addr ;
204128 if (st -> level == -1 ) {
205- pt_dump_seq_printf (m , "---[ %s ]---\n" , st -> marker -> name );
129+ pt_dump_seq_puts (m , "---[ Kernel Virtual Address Space ]---\n" );
206130 note_page_update_state (st , addr , prot , level );
207131 } else if (prot != st -> current_prot || level != st -> level ||
208132 addr >= st -> marker [1 ].start_address ) {
@@ -276,7 +200,7 @@ static int ptdump_show(struct seq_file *m, void *v)
276200 .check_wx = false,
277201 .wx_pages = 0 ,
278202 .start_address = 0 ,
279- .marker = address_markers ,
203+ .marker = markers ,
280204 };
281205
282206 get_online_mems ();
@@ -299,23 +223,65 @@ static int ptdump_cmp(const void *a, const void *b)
299223 if (ama -> start_address < amb -> start_address )
300224 return -1 ;
301225 /*
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.
226+ * If the start addresses of two markers are identical sort markers in an
227+ * order that considers areas contained within other areas correctly.
305228 */
229+ if (ama -> is_start && amb -> is_start ) {
230+ if (ama -> size > amb -> size )
231+ return -1 ;
232+ if (ama -> size < amb -> size )
233+ return 1 ;
234+ return 0 ;
235+ }
236+ if (!ama -> is_start && !amb -> is_start ) {
237+ if (ama -> size > amb -> size )
238+ return 1 ;
239+ if (ama -> size < amb -> size )
240+ return -1 ;
241+ return 0 ;
242+ }
306243 if (ama -> is_start )
307244 return 1 ;
308245 if (amb -> is_start )
309246 return -1 ;
310247 return 0 ;
311248}
312249
250+ static int add_marker (unsigned long start , unsigned long end , const char * name )
251+ {
252+ size_t oldsize , newsize ;
253+
254+ oldsize = markers_cnt * sizeof (* markers );
255+ newsize = oldsize + 2 * sizeof (* markers );
256+ if (!oldsize )
257+ markers = kvmalloc (newsize , GFP_KERNEL );
258+ else
259+ markers = kvrealloc (markers , oldsize , newsize , GFP_KERNEL );
260+ if (!markers )
261+ goto error ;
262+ markers [markers_cnt ].is_start = 1 ;
263+ markers [markers_cnt ].start_address = start ;
264+ markers [markers_cnt ].size = end - start ;
265+ markers [markers_cnt ].name = name ;
266+ markers_cnt ++ ;
267+ markers [markers_cnt ].is_start = 0 ;
268+ markers [markers_cnt ].start_address = end ;
269+ markers [markers_cnt ].size = end - start ;
270+ markers [markers_cnt ].name = name ;
271+ markers_cnt ++ ;
272+ return 0 ;
273+ error :
274+ markers_cnt = 0 ;
275+ return - ENOMEM ;
276+ }
277+
313278static int pt_dump_init (void )
314279{
315280#ifdef CONFIG_KFENCE
316281 unsigned long kfence_start = (unsigned long )__kfence_pool ;
317282#endif
318283 unsigned long lowcore = (unsigned long )get_lowcore ();
284+ int rc ;
319285
320286 /*
321287 * Figure out the maximum virtual address being accessible with the
@@ -324,41 +290,38 @@ static int pt_dump_init(void)
324290 */
325291 max_addr = (get_lowcore ()-> kernel_asce .val & _REGION_ENTRY_TYPE_MASK ) >> 2 ;
326292 max_addr = 1UL << (max_addr * 11 + 31 );
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 ;
331- address_markers [AMODE31_START_NR ].start_address = (unsigned long )__samode31 ;
332- address_markers [AMODE31_END_NR ].start_address = (unsigned long )__eamode31 ;
333- address_markers [MODULES_NR ].start_address = MODULES_VADDR ;
334- address_markers [MODULES_END_NR ].start_address = MODULES_END ;
335- address_markers [ABS_LOWCORE_NR ].start_address = __abs_lowcore ;
336- address_markers [ABS_LOWCORE_END_NR ].start_address = __abs_lowcore + ABS_LOWCORE_MAP_SIZE ;
337- address_markers [MEMCPY_REAL_NR ].start_address = __memcpy_real_area ;
338- address_markers [MEMCPY_REAL_END_NR ].start_address = __memcpy_real_area + MEMCPY_REAL_SIZE ;
339- address_markers [VMEMMAP_NR ].start_address = (unsigned long ) vmemmap ;
340- address_markers [VMEMMAP_END_NR ].start_address = (unsigned long )vmemmap + vmemmap_size ;
341- address_markers [VMALLOC_NR ].start_address = VMALLOC_START ;
342- address_markers [VMALLOC_END_NR ].start_address = VMALLOC_END ;
293+ /* start + end markers - must be added first */
294+ rc = add_marker (0 , -1UL , NULL );
295+ rc |= add_marker ((unsigned long )_stext , (unsigned long )_end , "Kernel Image" );
296+ rc |= add_marker (lowcore , lowcore + sizeof (struct lowcore ), "Lowcore" );
297+ rc |= add_marker (__identity_base , __identity_base + ident_map_size , "Identity Mapping" );
298+ rc |= add_marker ((unsigned long )__samode31 , (unsigned long )__eamode31 , "Amode31 Area" );
299+ rc |= add_marker (MODULES_VADDR , MODULES_END , "Modules Area" );
300+ rc |= add_marker (__abs_lowcore , __abs_lowcore + ABS_LOWCORE_MAP_SIZE , "Lowcore Area" );
301+ rc |= add_marker (__memcpy_real_area , __memcpy_real_area + MEMCPY_REAL_SIZE , "Real Memory Copy Area" );
302+ rc |= add_marker ((unsigned long )vmemmap , (unsigned long )vmemmap + vmemmap_size , "vmemmap Area" );
303+ rc |= add_marker (VMALLOC_START , VMALLOC_END , "vmalloc Area" );
343304#ifdef CONFIG_KFENCE
344- address_markers [KFENCE_START_NR ].start_address = kfence_start ;
345- address_markers [KFENCE_END_NR ].start_address = kfence_start + KFENCE_POOL_SIZE ;
305+ rc |= add_marker (kfence_start , kfence_start + KFENCE_POOL_SIZE , "KFence Pool" );
346306#endif
347307#ifdef CONFIG_KMSAN
348- address_markers [KMSAN_VMALLOC_SHADOW_START_NR ].start_address = KMSAN_VMALLOC_SHADOW_START ;
349- address_markers [KMSAN_VMALLOC_SHADOW_END_NR ].start_address = KMSAN_VMALLOC_SHADOW_END ;
350- address_markers [KMSAN_VMALLOC_ORIGIN_START_NR ].start_address = KMSAN_VMALLOC_ORIGIN_START ;
351- address_markers [KMSAN_VMALLOC_ORIGIN_END_NR ].start_address = KMSAN_VMALLOC_ORIGIN_END ;
352- address_markers [KMSAN_MODULES_SHADOW_START_NR ].start_address = KMSAN_MODULES_SHADOW_START ;
353- address_markers [KMSAN_MODULES_SHADOW_END_NR ].start_address = KMSAN_MODULES_SHADOW_END ;
354- address_markers [KMSAN_MODULES_ORIGIN_START_NR ].start_address = KMSAN_MODULES_ORIGIN_START ;
355- address_markers [KMSAN_MODULES_ORIGIN_END_NR ].start_address = KMSAN_MODULES_ORIGIN_END ;
308+ rc |= add_marker (KMSAN_VMALLOC_SHADOW_START , KMSAN_VMALLOC_SHADOW_END , "Kmsan vmalloc Shadow" );
309+ rc |= add_marker (KMSAN_VMALLOC_ORIGIN_START , KMSAN_VMALLOC_ORIGIN_END , "Kmsan vmalloc Origins" );
310+ rc |= add_marker (KMSAN_MODULES_SHADOW_START , KMSAN_MODULES_SHADOW_END , "Kmsan Modules Shadow" );
311+ rc |= add_marker (KMSAN_MODULES_ORIGIN_START , KMSAN_MODULES_ORIGIN_END , "Kmsan Modules Origins" );
312+ #endif
313+ #ifdef CONFIG_KASAN
314+ rc |= add_marker (KASAN_SHADOW_START , KASAN_SHADOW_END , "Kasan Shadow" );
356315#endif
357- sort (address_markers , ARRAY_SIZE (address_markers ) - 1 ,
358- sizeof (address_markers [0 ]), ptdump_cmp , NULL );
316+ if (rc )
317+ goto error ;
318+ sort (& markers [1 ], markers_cnt - 1 , sizeof (* markers ), ptdump_cmp , NULL );
359319#ifdef CONFIG_PTDUMP_DEBUGFS
360320 debugfs_create_file ("kernel_page_tables" , 0400 , NULL , NULL , & ptdump_fops );
361321#endif /* CONFIG_PTDUMP_DEBUGFS */
362322 return 0 ;
323+ error :
324+ kvfree (markers );
325+ return - ENOMEM ;
363326}
364327device_initcall (pt_dump_init );
0 commit comments