Skip to content

Commit d7e9ea0

Browse files
Nicolas Pitrenashif
authored andcommitted
arch/arm64/mmu: fix page table reference counting part 3
Commit f7e1164 ("arch/arm64/mmu: fix page table reference counting") missed another case where the freeing of a whole table "branch" didn't take into account the fact that some sub-tables might be shared and therefore must be cleared only if the reference count is down to 1. Signed-off-by: Nicolas Pitre <[email protected]>
1 parent 88d27cc commit d7e9ea0

File tree

1 file changed

+11
-2
lines changed

1 file changed

+11
-2
lines changed

arch/arm64/core/mmu.c

Lines changed: 11 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -102,6 +102,11 @@ static inline bool is_table_unused(uint64_t *table)
102102
return (table_usage(table, 0) & XLAT_PTE_COUNT_MASK) == 0;
103103
}
104104

105+
static inline bool is_table_single_referenced(uint64_t *table)
106+
{
107+
return table_usage(table, 0) < (2 * XLAT_REF_COUNT_UNIT);
108+
}
109+
105110
#ifdef CONFIG_TEST
106111
/* Hooks to let test code peek at table states */
107112

@@ -502,8 +507,12 @@ static void discard_table(uint64_t *table, unsigned int level)
502507

503508
for (i = 0U; i < Ln_XLAT_NUM_ENTRIES; i++) {
504509
if (is_table_desc(table[i], level)) {
505-
discard_table(pte_desc_table(table[i]), level + 1);
506-
dec_table_ref(pte_desc_table(table[i]));
510+
uint64_t *subtable = pte_desc_table(table[i]);
511+
512+
if (is_table_single_referenced(subtable)) {
513+
discard_table(subtable, level + 1);
514+
}
515+
dec_table_ref(subtable);
507516
}
508517
if (!is_free_desc(table[i])) {
509518
table[i] = 0U;

0 commit comments

Comments
 (0)