Skip to content

Commit cca547e

Browse files
mrutland-armRussell King
authored andcommitted
ARM: 8249/1: mm: dump: don't skip regions
Currently the arm page table dumping code starts dumping page tables from USER_PGTABLES_CEILING. This is unnecessary for skipping any entries related to userspace as the swapper_pg_dir does not contain such entries, and results in a couple of unfortuante side effects. Firstly, any kernel mappings which might exist below USER_PGTABLES_CEILING will not be accounted in the dump output. This masks any entries erroneously created below this address. Secondly, if the final page table entry walked is part of a valid mapping the page table dumping code will not log the region this entry is part of, as the final note_page call in walk_pgd will trigger an early return when 0 < USER_PGTABLES_CEILING. Luckily this isn't seen on contemporary systems as they typically don't have enough RAM to extend the linear mapping right to the end of the address space. Due to the way addr is constructed in the walk_* functions, it can never be less than USER_PGTABLES_CEILING when walking the page tables, so it is not necessary to avoid dereferencing invalid table addresses. The existing checks for st->current_prot and st->marker[1].start_address are sufficient to ensure we will not print and/or dereference garbage when trying to log information. This patch removes both problematic uses of USER_PGTABLES_CEILING from the arm page table dumping code, preventing both of these issues. We will now report any low mappings, and the final note_page call will not return early, ensuring all regions are logged. Signed-off-by: Mark Rutland <mark.rutland@arm.com> Cc: Steve Capper <steve.capper@linaro.org> Cc: Kees Cook <keescook@chromium.org> Cc: Will Deacon <will.deacon@arm.com> Signed-off-by: Russell King <rmk+kernel@arm.linux.org.uk>
1 parent 841ee23 commit cca547e

File tree

1 file changed

+2
-7
lines changed

1 file changed

+2
-7
lines changed

arch/arm/mm/dump.c

Lines changed: 2 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -220,9 +220,6 @@ static void note_page(struct pg_state *st, unsigned long addr, unsigned level, u
220220
static const char units[] = "KMGTPE";
221221
u64 prot = val & pg_level[level].mask;
222222

223-
if (addr < USER_PGTABLES_CEILING)
224-
return;
225-
226223
if (!st->level) {
227224
st->level = level;
228225
st->current_prot = prot;
@@ -308,15 +305,13 @@ static void walk_pgd(struct seq_file *m)
308305
pgd_t *pgd = swapper_pg_dir;
309306
struct pg_state st;
310307
unsigned long addr;
311-
unsigned i, pgdoff = USER_PGTABLES_CEILING / PGDIR_SIZE;
308+
unsigned i;
312309

313310
memset(&st, 0, sizeof(st));
314311
st.seq = m;
315312
st.marker = address_markers;
316313

317-
pgd += pgdoff;
318-
319-
for (i = pgdoff; i < PTRS_PER_PGD; i++, pgd++) {
314+
for (i = 0; i < PTRS_PER_PGD; i++, pgd++) {
320315
addr = i * PGDIR_SIZE;
321316
if (!pgd_none(*pgd)) {
322317
walk_pud(&st, pgd, addr);

0 commit comments

Comments
 (0)