Skip to content

Commit 7e4d4cf

Browse files
hcahcaVasily Gorbik
authored andcommitted
s390/mm/ptdump: Add support for relocated lowcore mapping
The page table dumper contains a hard coded assumption that the first mapped area starts at address zero. With a relocated lowcore this is not true anymore. Subsequently the first entry (lowcore) is printed as if it would contain everything from address zero until the end of the location of the lowcore area. Fix this by adding a single "Kernel Virtual Address Space" entry, which always starts at address zero. It ends when the lowcore area starts which is either address zero, or its relocated address. Reviewed-by: Sven Schnelle <[email protected]> Signed-off-by: Heiko Carstens <[email protected]> Signed-off-by: Vasily Gorbik <[email protected]>
1 parent 3739534 commit 7e4d4cf

File tree

1 file changed

+22
-13
lines changed

1 file changed

+22
-13
lines changed

arch/s390/mm/dump_pagetables.c

Lines changed: 22 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,8 @@ struct addr_marker {
2020
};
2121

2222
enum address_markers_idx {
23-
LOWCORE_START_NR = 0,
23+
KVA_NR = 0,
24+
LOWCORE_START_NR,
2425
LOWCORE_END_NR,
2526
AMODE31_START_NR,
2627
AMODE31_END_NR,
@@ -59,6 +60,7 @@ enum address_markers_idx {
5960
};
6061

6162
static struct addr_marker address_markers[] = {
63+
[KVA_NR] = {0, "Kernel Virtual Address Space"},
6264
[LOWCORE_START_NR] = {0, "Lowcore Start"},
6365
[LOWCORE_END_NR] = {0, "Lowcore End"},
6466
[IDENTITY_START_NR] = {0, "Identity Mapping Start"},
@@ -163,6 +165,19 @@ static void note_prot_wx(struct pg_state *st, unsigned long addr)
163165
st->wx_pages += (addr - st->start_address) / PAGE_SIZE;
164166
}
165167

168+
static void note_page_update_state(struct pg_state *st, unsigned long addr, unsigned int prot, int level)
169+
{
170+
struct seq_file *m = st->seq;
171+
172+
while (addr >= st->marker[1].start_address) {
173+
st->marker++;
174+
pt_dump_seq_printf(m, "---[ %s ]---\n", st->marker->name);
175+
}
176+
st->start_address = addr;
177+
st->current_prot = prot;
178+
st->level = level;
179+
}
180+
166181
static void note_page(struct ptdump_state *pt_st, unsigned long addr, int level, u64 val)
167182
{
168183
int width = sizeof(unsigned long) * 2;
@@ -186,9 +201,7 @@ static void note_page(struct ptdump_state *pt_st, unsigned long addr, int level,
186201
addr = max_addr;
187202
if (st->level == -1) {
188203
pt_dump_seq_printf(m, "---[ %s ]---\n", st->marker->name);
189-
st->start_address = addr;
190-
st->current_prot = prot;
191-
st->level = level;
204+
note_page_update_state(st, addr, prot, level);
192205
} else if (prot != st->current_prot || level != st->level ||
193206
addr >= st->marker[1].start_address) {
194207
note_prot_wx(st, addr);
@@ -202,13 +215,7 @@ static void note_page(struct ptdump_state *pt_st, unsigned long addr, int level,
202215
}
203216
pt_dump_seq_printf(m, "%9lu%c ", delta, *unit);
204217
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;
218+
note_page_update_state(st, addr, prot, level);
212219
}
213220
}
214221

@@ -303,15 +310,17 @@ static int pt_dump_init(void)
303310
#ifdef CONFIG_KFENCE
304311
unsigned long kfence_start = (unsigned long)__kfence_pool;
305312
#endif
313+
unsigned long lowcore = (unsigned long)get_lowcore();
314+
306315
/*
307316
* Figure out the maximum virtual address being accessible with the
308317
* kernel ASCE. We need this to keep the page table walker functions
309318
* from accessing non-existent entries.
310319
*/
311320
max_addr = (get_lowcore()->kernel_asce.val & _REGION_ENTRY_TYPE_MASK) >> 2;
312321
max_addr = 1UL << (max_addr * 11 + 31);
313-
address_markers[LOWCORE_START_NR].start_address = 0;
314-
address_markers[LOWCORE_END_NR].start_address = sizeof(struct lowcore);
322+
address_markers[LOWCORE_START_NR].start_address = lowcore;
323+
address_markers[LOWCORE_END_NR].start_address = lowcore + sizeof(struct lowcore);
315324
address_markers[IDENTITY_START_NR].start_address = __identity_base;
316325
address_markers[IDENTITY_END_NR].start_address = __identity_base + ident_map_size;
317326
address_markers[AMODE31_START_NR].start_address = (unsigned long)__samode31;

0 commit comments

Comments
 (0)