x86: tests: pagetables: fix assumptions

All RAM may not be mapped. Check the mapping for the main kernel
image and the locore if it exists.

Signed-off-by: Andrew Boie <andrew.p.boie@intel.com>
This commit is contained in:
Andrew Boie 2020-12-17 13:41:57 -08:00 committed by Anas Nashif
commit a7d8b3385a

View file

@ -15,11 +15,9 @@
#include <arch/x86/mmustructs.h> #include <arch/x86/mmustructs.h>
#include <x86_mmu.h> #include <x86_mmu.h>
#include <linker/linker-defs.h> #include <linker/linker-defs.h>
#include <mmu.h>
#include "main.h" #include "main.h"
#define VM_BASE ((uint8_t *)CONFIG_KERNEL_VM_BASE)
#define VM_LIMIT (VM_BASE + CONFIG_KERNEL_RAM_SIZE)
#ifdef CONFIG_X86_64 #ifdef CONFIG_X86_64
#define PT_LEVEL 3 #define PT_LEVEL 3
#elif CONFIG_X86_PAE #elif CONFIG_X86_PAE
@ -45,6 +43,10 @@ extern char _locore_start[];
extern char _locore_size[]; extern char _locore_size[];
extern char _lorodata_start[]; extern char _lorodata_start[];
extern char _lorodata_size[]; extern char _lorodata_size[];
extern char _lodata_end[];
#define LOCORE_START ((uint8_t *)&_locore_start)
#define LOCORE_END ((uint8_t *)&_lodata_end)
#endif #endif
#ifdef CONFIG_COVERAGE_GCOV #ifdef CONFIG_COVERAGE_GCOV
@ -52,6 +54,21 @@ extern char __gcov_bss_start[];
extern char __gcov_bss_size[]; extern char __gcov_bss_size[];
#endif #endif
static pentry_t get_entry(pentry_t *flags, void *addr)
{
int level;
pentry_t entry;
z_x86_pentry_get(&level, &entry, z_x86_page_tables_get(), addr);
zassert_true((entry & MMU_P) != 0,
"non-present RAM entry");
zassert_equal(level, PT_LEVEL, "bigpage found");
*flags = entry & FLAGS_MASK;
return entry;
}
/** /**
* Test that MMU flags on RAM virtual address range are set properly * Test that MMU flags on RAM virtual address range are set properly
* *
@ -61,21 +78,16 @@ void test_ram_perms(void)
{ {
uint8_t *pos; uint8_t *pos;
for (pos = VM_BASE; pos < VM_LIMIT; pos += CONFIG_MMU_PAGE_SIZE) { pentry_t entry, flags, expected;
int level;
pentry_t entry, flags, expected;
for (pos = Z_KERNEL_VIRT_START; pos < Z_KERNEL_VIRT_END;
pos += CONFIG_MMU_PAGE_SIZE) {
if (pos == NULL) { if (pos == NULL) {
/* We have another test specifically for NULL page */ /* We have another test specifically for NULL page */
continue; continue;
} }
z_x86_pentry_get(&level, &entry, z_x86_page_tables_get(), pos); entry = get_entry(&flags, pos);
zassert_true((entry & MMU_P) != 0,
"non-present RAM entry");
zassert_equal(level, PT_LEVEL, "bigpage found");
flags = entry & FLAGS_MASK;
if (!IS_ENABLED(CONFIG_SRAM_REGION_PERMISSIONS)) { if (!IS_ENABLED(CONFIG_SRAM_REGION_PERMISSIONS)) {
expected = MMU_P | MMU_RW; expected = MMU_P | MMU_RW;
@ -87,20 +99,6 @@ void test_ram_perms(void)
} else if (IN_REGION(__gcov_bss, pos)) { } else if (IN_REGION(__gcov_bss, pos)) {
expected = MMU_P | MMU_RW | MMU_US | MMU_XD; expected = MMU_P | MMU_RW | MMU_US | MMU_XD;
#endif #endif
#ifdef CONFIG_X86_64
} else if (IN_REGION(_locore, pos)) {
if (IS_ENABLED(CONFIG_X86_KPTI)) {
expected = MMU_P | MMU_US;
} else {
expected = MMU_P;
}
} else if (IN_REGION(_lorodata, pos)) {
if (IS_ENABLED(CONFIG_X86_KPTI)) {
expected = MMU_P | MMU_US | MMU_XD;
} else {
expected = MMU_P | MMU_XD;
}
#endif /* CONFIG_X86_64 */
#if !defined(CONFIG_X86_KPTI) && !defined(CONFIG_X86_COMMON_PAGE_TABLE) && \ #if !defined(CONFIG_X86_KPTI) && !defined(CONFIG_X86_COMMON_PAGE_TABLE) && \
defined(CONFIG_USERSPACE) defined(CONFIG_USERSPACE)
} else if (IN_REGION(_app_smem, pos)) { } else if (IN_REGION(_app_smem, pos)) {
@ -125,12 +123,42 @@ void test_ram_perms(void)
*/ */
expected = MMU_P | MMU_RW | MMU_XD; expected = MMU_P | MMU_RW | MMU_XD;
} }
zassert_equal(flags, expected, zassert_equal(flags, expected,
"bad flags " PRI_ENTRY " at %p, expected " "bad flags " PRI_ENTRY " at %p, expected "
PRI_ENTRY, flags, pos, expected); PRI_ENTRY, flags, pos, expected);
} }
#ifdef CONFIG_X86_64
/* Check the locore too */
for (pos = LOCORE_START; pos < LOCORE_END;
pos += CONFIG_MMU_PAGE_SIZE) {
if (pos == NULL) {
/* We have another test specifically for NULL page */
continue;
}
entry = get_entry(&flags, pos);
if (IN_REGION(_locore, pos)) {
if (IS_ENABLED(CONFIG_X86_KPTI)) {
expected = MMU_P | MMU_US;
} else {
expected = MMU_P;
}
} else if (IN_REGION(_lorodata, pos)) {
if (IS_ENABLED(CONFIG_X86_KPTI)) {
expected = MMU_P | MMU_US | MMU_XD;
} else {
expected = MMU_P | MMU_XD;
}
} else {
expected = MMU_P | MMU_RW | MMU_XD;
}
zassert_equal(flags, expected,
"bad flags " PRI_ENTRY " at %p, expected "
PRI_ENTRY, flags, pos, expected);
}
#endif /* CONFIG_X86_64 */
} }
/** /**