-
Notifications
You must be signed in to change notification settings - Fork 6.7k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
tests: kernel: App to validate boot time page table #1286
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,5 @@ | ||
include($ENV{ZEPHYR_BASE}/cmake/app/boilerplate.cmake NO_POLICY_SCOPE) | ||
project(NONE) | ||
|
||
FILE(GLOB app_sources src/*.c) | ||
target_sources(app PRIVATE ${app_sources}) |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,44 @@ | ||
Title: x86 boot time page table validation | ||
|
||
Description: | ||
|
||
This test is for x86 to validate boot time page table faults. | ||
Testcase outputs to console, for corresponding result, on validating | ||
boot page table. | ||
|
||
The checks are for param of the interested memory region | ||
that are value->p, value->us and value->rw. These are permissoin associated | ||
with the interested memory regions. | ||
|
||
-------------------------------------------------------------------------------- | ||
|
||
Build and Run: | ||
|
||
This testcase will output to console. It can be built and executed | ||
on QEMU as follows: | ||
|
||
mkdir build && cd build | ||
cmake -DBOARD=qemu_x86 .. | ||
make run | ||
|
||
-------------------------------------------------------------------------------- | ||
|
||
Troubleshooting/Problem Solving: | ||
|
||
Issues will occur if the object files and other related files generated from | ||
previous build are not discarded. In that scenario below step can be followed | ||
|
||
make pristine # remove old outdir directory | ||
# discard results/files generated from previous build | ||
|
||
-------------------------------------------------------------------------------- | ||
|
||
Sample Output: | ||
|
||
Running test suite boot_page_table_validate | ||
=================================================================== | ||
starting test - test_boot_page_table | ||
PASS - test_boot_page_table. | ||
=================================================================== | ||
=================================================================== | ||
PROJECT EXECUTION SUCCESSFUL |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1 @@ | ||
CONFIG_ZTEST=y |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,146 @@ | ||
/* | ||
* Copyright (c) 2017 Intel Corporation | ||
* | ||
* SPDX-License-Identifier: Apache-2.0 | ||
*/ | ||
|
||
#include <zephyr.h> | ||
#include <misc/printk.h> | ||
#include <mmustructs.h> | ||
#include <ztest.h> | ||
#include "boot_page_table.h" | ||
|
||
#define MEMORY_REG_NUM 4 | ||
|
||
MMU_BOOT_REGION(START_ADDR_RANGE1, ADDR_SIZE, REGION_PERM); | ||
MMU_BOOT_REGION(START_ADDR_RANGE2, ADDR_SIZE, REGION_PERM); | ||
MMU_BOOT_REGION(START_ADDR_RANGE3, ADDR_SIZE, REGION_PERM); | ||
MMU_BOOT_REGION(START_ADDR_RANGE4, ADDR_SIZE, REGION_PERM); | ||
|
||
static int check_param(union x86_mmu_pae_pte *value, uint32_t perm) | ||
{ | ||
u32_t status = (value->rw == ((perm & MMU_PTE_RW_MASK) >> 0x1)); | ||
|
||
status &= (value->us == ((perm & MMU_PTE_US_MASK) >> 0x2)); | ||
status &= value->p; | ||
return status; | ||
} | ||
|
||
static int check_param_nonset_region(union x86_mmu_pae_pte *value, | ||
uint32_t perm) | ||
{ | ||
u32_t status = (value->rw == 0); | ||
|
||
status &= (value->us == 0); | ||
status &= (value->p == 0); | ||
return status; | ||
} | ||
|
||
static int starting_addr_range(u32_t start_addr_range) | ||
{ | ||
|
||
u32_t addr_range, status = true; | ||
union x86_mmu_pae_pte *value; | ||
|
||
for (addr_range = start_addr_range; addr_range <= | ||
(start_addr_range + STARTING_ADDR_RANGE_LMT); | ||
addr_range += 0x1000) { | ||
value = X86_MMU_GET_PTE(addr_range); | ||
status &= check_param(value, REGION_PERM); | ||
if (status == 0) { | ||
printk("error at %d permissions %d\n", | ||
addr_range, REGION_PERM); | ||
TC_PRINT("%s failed\n", __func__); | ||
return TC_FAIL; | ||
} | ||
} | ||
return TC_PASS; | ||
} | ||
|
||
static int before_start_addr_range(u32_t start_addr_range) | ||
{ | ||
u32_t addr_range, status = true; | ||
union x86_mmu_pae_pte *value; | ||
|
||
for (addr_range = start_addr_range - 0x7000; | ||
addr_range < (start_addr_range); addr_range += 0x1000) { | ||
|
||
value = X86_MMU_GET_PTE(addr_range); | ||
status &= check_param_nonset_region(value, | ||
REGION_PERM); | ||
if (status == 0) { | ||
TC_PRINT("%s failed\n", __func__); | ||
printk("error at %d permissions %d\n", | ||
addr_range, REGION_PERM); | ||
return TC_FAIL; | ||
|
||
} | ||
} | ||
return TC_PASS; | ||
} | ||
|
||
static int ending_start_addr_range(u32_t start_addr_range) | ||
{ | ||
u32_t addr_range, status = true; | ||
union x86_mmu_pae_pte *value; | ||
|
||
for (addr_range = start_addr_range + ADDR_SIZE; addr_range < | ||
(start_addr_range + ADDR_SIZE + 0x10000); | ||
addr_range += 0x1000) { | ||
value = X86_MMU_GET_PTE(addr_range); | ||
status &= check_param_nonset_region(value, REGION_PERM); | ||
if (status == 0) { | ||
TC_PRINT("%s failed\n", __func__); | ||
printk("error at %d permissions %d\n", | ||
addr_range, REGION_PERM); | ||
return TC_FAIL; | ||
|
||
} | ||
} | ||
return TC_PASS; | ||
} | ||
|
||
int boot_page_table(void) | ||
{ | ||
u32_t start_addr_range; | ||
int iterator = 0, check = 0; | ||
|
||
for (iterator = 0; iterator < MEMORY_REG_NUM; iterator++) { | ||
switch (iterator) { | ||
|
||
case 0: | ||
start_addr_range = START_ADDR_RANGE1; | ||
break; | ||
|
||
case 1: | ||
start_addr_range = START_ADDR_RANGE2; | ||
break; | ||
|
||
case 2: | ||
start_addr_range = START_ADDR_RANGE3; | ||
break; | ||
|
||
case 3: | ||
start_addr_range = START_ADDR_RANGE4; | ||
break; | ||
default: | ||
break; | ||
} | ||
check = starting_addr_range(start_addr_range); | ||
if (check == TC_FAIL) | ||
return TC_FAIL; | ||
check = before_start_addr_range(start_addr_range); | ||
if (check == TC_FAIL) | ||
return TC_FAIL; | ||
check = ending_start_addr_range(start_addr_range); | ||
if (check == TC_FAIL) | ||
return TC_FAIL; | ||
|
||
} | ||
return TC_PASS; | ||
} | ||
|
||
void test_boot_page_table(void) | ||
{ | ||
zassert_true(boot_page_table() == TC_PASS, NULL); | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,43 @@ | ||
/* | ||
* Copyright (c) 2017 Intel Corporation | ||
* | ||
* SPDX-License-Identifier: Apache-2.0 | ||
*/ | ||
#ifndef __BOOT_PAGE_TABLE_H__ | ||
#define __BOOT_PAGE_TABLE_H__ | ||
|
||
#ifndef X86_MMU_GET_PT_ADDR | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. missing copyright/license header There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. you also need a header guard here |
||
|
||
/* Helper macros to ease the usage of the MMU page table structures. | ||
* Returns the Page table address for the particular address. | ||
* Page Table address(returned value) is always 4KBytes aligned. | ||
*/ | ||
#define X86_MMU_GET_PT_ADDR(addr) \ | ||
((struct x86_mmu_page_table *)\ | ||
(X86_MMU_GET_PDE(addr)->page_table << MMU_PAGE_SHIFT)) | ||
|
||
#endif | ||
|
||
#ifndef X86_MMU_GET_PTE | ||
/* Returns the page table entry for the addr | ||
* use the union to extract page entry related information. | ||
*/ | ||
|
||
#define X86_MMU_GET_PTE(addr)\ | ||
((union x86_mmu_pae_pte *)\ | ||
(&X86_MMU_GET_PT_ADDR(addr)->entry[MMU_PAGE_NUM(addr)])) | ||
#endif | ||
|
||
#define MMU_READ 0x00 | ||
#define MMU_WRITE 0x01 | ||
#define MMU_READ_WRITE (MMU_READ | MMU_WRITE) | ||
#define MMU_PAGE_USER 0x02 | ||
#define START_ADDR_RANGE1 0x12300000 | ||
#define START_ADDR_RANGE2 0x12340000 | ||
#define START_ADDR_RANGE3 0x12400000 | ||
#define START_ADDR_RANGE4 0x12460000 | ||
#define ADDR_SIZE 0x1000 | ||
#define STARTING_ADDR_RANGE_LMT 0x0009ff | ||
#define START_ADR_RANGE_OVRLP_LMT 0x001000 | ||
#define REGION_PERM (MMU_READ_WRITE | MMU_PAGE_USER) | ||
#endif | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. move line 37 (#endif )to line 27 There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. #endif moved to line 27 |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,15 @@ | ||
/* | ||
* Copyright (c) 2017 Intel Corporation | ||
* | ||
* SPDX-License-Identifier: Apache-2.0 | ||
*/ | ||
|
||
#include <ztest.h> | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. missing copyright/license header |
||
extern void test_boot_page_table(void); | ||
|
||
void test_main(void) | ||
{ | ||
ztest_test_suite(boot_page_table_validate, | ||
ztest_unit_test(test_boot_page_table)); | ||
ztest_run_test_suite(boot_page_table_validate); | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,5 @@ | ||
tests: | ||
- test: | ||
platform_whitelist: qemu_x86 | ||
platform_exclude: qemu_x86_nommu | ||
tags: kernel |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
missing copyright/license header