Type for page table.
A page table is an array of PTEs but a pte_t pointer is overloaded and
causes confusion when reading. This new type makes it explicit that the
pointer is to a page table.
Change-Id: I167ed43098e6ab1df7c8b680604ba076dd9b74db
diff --git a/src/mm_test.cc b/src/mm_test.cc
index d4c1d32..7990d27 100644
--- a/src/mm_test.cc
+++ b/src/mm_test.cc
@@ -31,7 +31,6 @@
using ::testing::Eq;
constexpr size_t TEST_HEAP_SIZE = PAGE_SIZE * 10;
-constexpr size_t ENTRY_COUNT = PAGE_SIZE / sizeof(pte_t);
const int TOP_LEVEL = arch_mm_max_level(0);
const pte_t ABSENT_ENTRY = arch_mm_absent_pte(TOP_LEVEL);
@@ -45,22 +44,41 @@
}
/**
+ * Get the page table from the physical address.
+ */
+struct mm_page_table *page_table_from_pa(paddr_t pa)
+{
+ return reinterpret_cast<struct mm_page_table *>(
+ ptr_from_va(va_from_pa(pa)));
+}
+
+/**
+ * Allocate a page table.
+ */
+struct mm_page_table *alloc_page_table()
+{
+ return reinterpret_cast<struct mm_page_table *>(halloc_aligned(
+ sizeof(struct mm_page_table), alignof(struct mm_page_table)));
+}
+
+/**
* Fill a ptable with absent entries.
*/
-void init_absent(pte_t *table)
+void init_absent(struct mm_page_table *table)
{
- for (uint64_t i = 0; i < ENTRY_COUNT; ++i) {
- table[i] = ABSENT_ENTRY;
+ for (uint64_t i = 0; i < MM_PTE_PER_PAGE; ++i) {
+ table->entries[i] = ABSENT_ENTRY;
}
}
/**
* Fill a ptable with block entries.
*/
-void init_blocks(pte_t *table, int level, paddr_t start_address, uint64_t attrs)
+void init_blocks(struct mm_page_table *table, int level, paddr_t start_address,
+ uint64_t attrs)
{
- for (uint64_t i = 0; i < ENTRY_COUNT; ++i) {
- table[i] = arch_mm_block_pte(
+ for (uint64_t i = 0; i < MM_PTE_PER_PAGE; ++i) {
+ table->entries[i] = arch_mm_block_pte(
level, pa_add(start_address, i * mm_entry_size(level)),
attrs);
}
@@ -74,15 +92,15 @@
auto test_heap = std::make_unique<uint8_t[]>(TEST_HEAP_SIZE);
halloc_init((size_t)test_heap.get(), TEST_HEAP_SIZE);
- pte_t *table = (pte_t *)halloc_aligned(PAGE_SIZE, PAGE_SIZE);
+ struct mm_page_table *table = alloc_page_table();
init_absent(table);
struct mm_ptable ptable;
ptable.table = pa_init((uintpaddr_t)table);
mm_ptable_defrag(&ptable, 0);
- for (uint64_t i = 0; i < ENTRY_COUNT; ++i) {
- EXPECT_THAT(table[i], Eq(ABSENT_ENTRY)) << "i=" << i;
+ for (uint64_t i = 0; i < MM_PTE_PER_PAGE; ++i) {
+ EXPECT_THAT(table->entries[i], Eq(ABSENT_ENTRY)) << "i=" << i;
}
}
@@ -95,20 +113,20 @@
auto test_heap = std::make_unique<uint8_t[]>(TEST_HEAP_SIZE);
halloc_init((size_t)test_heap.get(), TEST_HEAP_SIZE);
- pte_t *subtable_a = (pte_t *)halloc_aligned(PAGE_SIZE, PAGE_SIZE);
- pte_t *subtable_aa = (pte_t *)halloc_aligned(PAGE_SIZE, PAGE_SIZE);
- pte_t *subtable_b = (pte_t *)halloc_aligned(PAGE_SIZE, PAGE_SIZE);
- pte_t *table = (pte_t *)halloc_aligned(PAGE_SIZE, PAGE_SIZE);
+ struct mm_page_table *subtable_a = alloc_page_table();
+ struct mm_page_table *subtable_aa = alloc_page_table();
+ struct mm_page_table *subtable_b = alloc_page_table();
+ struct mm_page_table *table = alloc_page_table();
init_absent(subtable_a);
init_absent(subtable_aa);
init_absent(subtable_b);
init_absent(table);
- subtable_a[3] = arch_mm_table_pte(TOP_LEVEL - 1,
- pa_init((uintpaddr_t)subtable_aa));
- table[0] =
+ subtable_a->entries[3] = arch_mm_table_pte(
+ TOP_LEVEL - 1, pa_init((uintpaddr_t)subtable_aa));
+ table->entries[0] =
arch_mm_table_pte(TOP_LEVEL, pa_init((uintpaddr_t)subtable_a));
- table[5] =
+ table->entries[5] =
arch_mm_table_pte(TOP_LEVEL, pa_init((uintpaddr_t)subtable_b));
struct mm_ptable ptable;
@@ -116,8 +134,8 @@
mm_ptable_defrag(&ptable, 0);
- for (uint64_t i = 0; i < ENTRY_COUNT; ++i) {
- EXPECT_THAT(table[i], Eq(ABSENT_ENTRY)) << "i=" << i;
+ for (uint64_t i = 0; i < MM_PTE_PER_PAGE; ++i) {
+ EXPECT_THAT(table->entries[i], Eq(ABSENT_ENTRY)) << "i=" << i;
}
}
@@ -130,10 +148,10 @@
auto test_heap = std::make_unique<uint8_t[]>(TEST_HEAP_SIZE);
halloc_init((size_t)test_heap.get(), TEST_HEAP_SIZE);
- pte_t *subtable_a = (pte_t *)halloc_aligned(PAGE_SIZE, PAGE_SIZE);
- pte_t *subtable_aa = (pte_t *)halloc_aligned(PAGE_SIZE, PAGE_SIZE);
- pte_t *subtable_b = (pte_t *)halloc_aligned(PAGE_SIZE, PAGE_SIZE);
- pte_t *table = (pte_t *)halloc_aligned(PAGE_SIZE, PAGE_SIZE);
+ struct mm_page_table *subtable_a = alloc_page_table();
+ struct mm_page_table *subtable_aa = alloc_page_table();
+ struct mm_page_table *subtable_b = alloc_page_table();
+ struct mm_page_table *table = alloc_page_table();
init_blocks(subtable_a, TOP_LEVEL - 1, pa_init(0), 0);
init_blocks(subtable_aa, TOP_LEVEL - 2,
pa_init(3 * mm_entry_size(TOP_LEVEL - 1)), 0);
@@ -141,11 +159,11 @@
pa_init(5 * mm_entry_size(TOP_LEVEL)), 0);
init_blocks(table, TOP_LEVEL, pa_init(0), 0);
- subtable_a[3] = arch_mm_table_pte(TOP_LEVEL - 1,
- pa_init((uintpaddr_t)subtable_aa));
- table[0] =
+ subtable_a->entries[3] = arch_mm_table_pte(
+ TOP_LEVEL - 1, pa_init((uintpaddr_t)subtable_aa));
+ table->entries[0] =
arch_mm_table_pte(TOP_LEVEL, pa_init((uintpaddr_t)subtable_a));
- table[5] =
+ table->entries[5] =
arch_mm_table_pte(TOP_LEVEL, pa_init((uintpaddr_t)subtable_b));
struct mm_ptable ptable;
@@ -153,12 +171,13 @@
mm_ptable_defrag(&ptable, 0);
- for (uint64_t i = 0; i < ENTRY_COUNT; ++i) {
- EXPECT_TRUE(arch_mm_pte_is_present(table[i], TOP_LEVEL))
+ for (uint64_t i = 0; i < MM_PTE_PER_PAGE; ++i) {
+ EXPECT_TRUE(
+ arch_mm_pte_is_present(table->entries[i], TOP_LEVEL))
<< "i=" << i;
- EXPECT_TRUE(arch_mm_pte_is_block(table[i], TOP_LEVEL))
+ EXPECT_TRUE(arch_mm_pte_is_block(table->entries[i], TOP_LEVEL))
<< "i=" << i;
- EXPECT_THAT(pa_addr(arch_mm_block_from_pte(table[i])),
+ EXPECT_THAT(pa_addr(arch_mm_block_from_pte(table->entries[i])),
Eq(i * mm_entry_size(TOP_LEVEL)))
<< "i=" << i;
}
@@ -170,7 +189,7 @@
auto test_heap = std::make_unique<uint8_t[]>(TEST_HEAP_SIZE);
halloc_init((size_t)test_heap.get(), TEST_HEAP_SIZE);
- pte_t *table = (pte_t *)halloc_aligned(PAGE_SIZE, PAGE_SIZE);
+ struct mm_page_table *table = alloc_page_table();
init_absent(table);
struct mm_ptable ptable;
@@ -178,8 +197,8 @@
EXPECT_TRUE(mm_ptable_unmap_hypervisor(&ptable, 0));
- for (uint64_t i = 0; i < ENTRY_COUNT; ++i) {
- EXPECT_THAT(table[i], Eq(ABSENT_ENTRY)) << "i=" << i;
+ for (uint64_t i = 0; i < MM_PTE_PER_PAGE; ++i) {
+ EXPECT_THAT(table->entries[i], Eq(ABSENT_ENTRY)) << "i=" << i;
}
}
@@ -191,17 +210,18 @@
auto test_heap = std::make_unique<uint8_t[]>(TEST_HEAP_SIZE);
halloc_init((size_t)test_heap.get(), TEST_HEAP_SIZE);
- pte_t *table = (pte_t *)halloc_aligned(PAGE_SIZE, PAGE_SIZE);
- pte_t *subtable_a = (pte_t *)halloc_aligned(PAGE_SIZE, PAGE_SIZE);
- pte_t *subtable_aa = (pte_t *)halloc_aligned(PAGE_SIZE, PAGE_SIZE);
- init_absent(table);
+ struct mm_page_table *subtable_a = alloc_page_table();
+ struct mm_page_table *subtable_aa = alloc_page_table();
+ struct mm_page_table *table = alloc_page_table();
init_absent(subtable_a);
init_absent(subtable_aa);
+ init_absent(table);
- subtable_aa[0] = arch_mm_block_pte(TOP_LEVEL - 2, pa_init(0), 0);
- subtable_a[0] = arch_mm_table_pte(TOP_LEVEL - 1,
- pa_init((uintpaddr_t)subtable_aa));
- table[0] =
+ subtable_aa->entries[0] =
+ arch_mm_block_pte(TOP_LEVEL - 2, pa_init(0), 0);
+ subtable_a->entries[0] = arch_mm_table_pte(
+ TOP_LEVEL - 1, pa_init((uintpaddr_t)subtable_aa));
+ table->entries[0] =
arch_mm_table_pte(TOP_LEVEL, pa_init((uintpaddr_t)subtable_a));
struct mm_ptable ptable;
@@ -209,8 +229,8 @@
EXPECT_TRUE(mm_vm_unmap(&ptable, pa_init(0), pa_init(1), 0));
- for (uint64_t i = 0; i < ENTRY_COUNT; ++i) {
- EXPECT_THAT(table[i], Eq(ABSENT_ENTRY)) << "i=" << i;
+ for (uint64_t i = 0; i < MM_PTE_PER_PAGE; ++i) {
+ EXPECT_THAT(table->entries[i], Eq(ABSENT_ENTRY)) << "i=" << i;
}
}
@@ -223,7 +243,7 @@
halloc_init((size_t)test_heap.get(), TEST_HEAP_SIZE);
/* Start with an empty page table. */
- pte_t *table = (pte_t *)halloc_aligned(PAGE_SIZE, PAGE_SIZE);
+ struct mm_page_table *table = alloc_page_table();
init_absent(table);
struct mm_ptable ptable;
ptable.table = pa_init((uintpaddr_t)table);
@@ -235,23 +255,28 @@
EXPECT_THAT(ipa_addr(ipa), Eq(0));
/* Check that the first page is mapped, and nothing else. */
- for (uint64_t i = 1; i < ENTRY_COUNT; ++i) {
- EXPECT_THAT(table[i], Eq(ABSENT_ENTRY)) << "i=" << i;
+ for (uint64_t i = 1; i < MM_PTE_PER_PAGE; ++i) {
+ EXPECT_THAT(table->entries[i], Eq(ABSENT_ENTRY)) << "i=" << i;
}
- ASSERT_TRUE(arch_mm_pte_is_table(table[0], TOP_LEVEL));
- pte_t *subtable_a = (pte_t *)ptr_from_va(
- va_from_pa(arch_mm_table_from_pte(table[0])));
- for (uint64_t i = 1; i < ENTRY_COUNT; ++i) {
- EXPECT_THAT(subtable_a[i], Eq(ABSENT_ENTRY)) << "i=" << i;
+ ASSERT_TRUE(arch_mm_pte_is_table(table->entries[0], TOP_LEVEL));
+ struct mm_page_table *subtable_a =
+ page_table_from_pa(arch_mm_table_from_pte(table->entries[0]));
+ for (uint64_t i = 1; i < MM_PTE_PER_PAGE; ++i) {
+ EXPECT_THAT(subtable_a->entries[i], Eq(ABSENT_ENTRY))
+ << "i=" << i;
}
- ASSERT_TRUE(arch_mm_pte_is_table(subtable_a[0], TOP_LEVEL - 1));
- pte_t *subtable_aa = (pte_t *)ptr_from_va(
- va_from_pa(arch_mm_table_from_pte(subtable_a[0])));
- for (uint64_t i = 1; i < ENTRY_COUNT; ++i) {
- EXPECT_THAT(subtable_aa[i], Eq(ABSENT_ENTRY)) << "i=" << i;
+ ASSERT_TRUE(
+ arch_mm_pte_is_table(subtable_a->entries[0], TOP_LEVEL - 1));
+ struct mm_page_table *subtable_aa = page_table_from_pa(
+ arch_mm_table_from_pte(subtable_a->entries[0]));
+ for (uint64_t i = 1; i < MM_PTE_PER_PAGE; ++i) {
+ EXPECT_THAT(subtable_aa->entries[i], Eq(ABSENT_ENTRY))
+ << "i=" << i;
}
- EXPECT_TRUE(arch_mm_pte_is_block(subtable_aa[0], TOP_LEVEL - 2));
- EXPECT_THAT(pa_addr(arch_mm_block_from_pte(subtable_aa[0])), Eq(0));
+ EXPECT_TRUE(
+ arch_mm_pte_is_block(subtable_aa->entries[0], TOP_LEVEL - 2));
+ EXPECT_THAT(pa_addr(arch_mm_block_from_pte(subtable_aa->entries[0])),
+ Eq(0));
}
/** Mapping a range that is already mapped should be a no-op. */
@@ -261,7 +286,7 @@
halloc_init((size_t)test_heap.get(), TEST_HEAP_SIZE);
/* Start with a full page table mapping everything. */
- pte_t *table = (pte_t *)halloc_aligned(PAGE_SIZE, PAGE_SIZE);
+ struct mm_page_table *table = alloc_page_table();
init_blocks(table, TOP_LEVEL, pa_init(0), 0);
struct mm_ptable ptable;
ptable.table = pa_init((uintpaddr_t)table);
@@ -276,8 +301,8 @@
* The table should still be full of blocks, with no subtables or
* anything else.
*/
- for (uint64_t i = 0; i < ENTRY_COUNT; ++i) {
- EXPECT_TRUE(arch_mm_pte_is_block(table[i], TOP_LEVEL))
+ for (uint64_t i = 0; i < MM_PTE_PER_PAGE; ++i) {
+ EXPECT_TRUE(arch_mm_pte_is_block(table->entries[i], TOP_LEVEL))
<< "i=" << i;
}
}