diff mbox series

[kvm-unit-tests,13/14] x86: Clean up the global, page_table_levels, in access.c

Message ID 20211110212001.3745914-14-aaronlewis@google.com (mailing list archive)
State New, archived
Headers show
Series Run access test in an L2 guest | expand

Commit Message

Aaron Lewis Nov. 10, 2021, 9:20 p.m. UTC
Remove the global, page table levels, from access.c and store it in the
test struct ac_test_t instead.

Signed-off-by: Aaron Lewis <aaronlewis@google.com>
---
 x86/access.c      | 50 ++++++++++++++++++++++++-----------------------
 x86/access.h      |  5 +++--
 x86/access_test.c |  6 ++----
 3 files changed, 31 insertions(+), 30 deletions(-)
diff mbox series

Patch

diff --git a/x86/access.c b/x86/access.c
index f832385..c5e71db 100644
--- a/x86/access.c
+++ b/x86/access.c
@@ -14,7 +14,6 @@  static _Bool verbose = false;
 
 typedef unsigned long pt_element_t;
 static int invalid_mask;
-int page_table_levels;
 
 #define PT_BASE_ADDR_MASK ((pt_element_t)((((pt_element_t)1 << 36) - 1) & PAGE_MASK))
 #define PT_PSE_BASE_ADDR_MASK (PT_BASE_ADDR_MASK & ~(1ull << 21))
@@ -174,6 +173,7 @@  typedef struct {
 	pt_element_t ignore_pde;
 	int expected_fault;
 	unsigned expected_error;
+	int page_table_levels;
 } ac_test_t;
 
 typedef struct {
@@ -278,13 +278,14 @@  static void ac_env_int(ac_pool_t *pool)
 	pool->pt_pool_current = 0;
 }
 
-static void ac_test_init(ac_test_t *at, void *virt)
+static void ac_test_init(ac_test_t *at, void *virt, int page_table_levels)
 {
 	set_efer_nx(1);
 	set_cr0_wp(1);
 	at->flags = 0;
 	at->virt = virt;
 	at->phys = 32 * 1024 * 1024;
+	at->page_table_levels = page_table_levels;
 }
 
 static int ac_test_bump_one(ac_test_t *at)
@@ -518,7 +519,7 @@  static void __ac_setup_specific_pages(ac_test_t *at, ac_pool_t *pool, bool reuse
 		ac_test_reset_pt_pool(pool);
 
 	at->ptep = 0;
-	for (int i = page_table_levels; i >= 1 && (i >= 2 || !F(AC_PDE_PSE)); --i) {
+	for (int i = at->page_table_levels; i >= 1 && (i >= 2 || !F(AC_PDE_PSE)); --i) {
 		pt_element_t *vroot = va(root & PT_BASE_ADDR_MASK);
 		unsigned index = PT_INDEX((unsigned long)at->virt, i);
 		pt_element_t pte = 0;
@@ -635,7 +636,7 @@  static void dump_mapping(ac_test_t *at)
 	int i;
 
 	printf("Dump mapping: address: %p\n", at->virt);
-	for (i = page_table_levels; i >= 1 && (i >= 2 || !F(AC_PDE_PSE)); --i) {
+	for (i = at->page_table_levels; i >= 1 && (i >= 2 || !F(AC_PDE_PSE)); --i) {
 		pt_element_t *vroot = va(root & PT_BASE_ADDR_MASK);
 		unsigned index = PT_INDEX((unsigned long)at->virt, i);
 		pt_element_t pte = vroot[index];
@@ -812,12 +813,12 @@  static void ac_test_show(ac_test_t *at)
  * This test case is used to triger the bug which is fixed by
  * commit e09e90a5 in the kvm tree
  */
-static int corrupt_hugepage_triger(ac_pool_t *pool)
+static int corrupt_hugepage_triger(ac_pool_t *pool, int page_table_levels)
 {
 	ac_test_t at1, at2;
 
-	ac_test_init(&at1, (void *)(0x123400000000));
-	ac_test_init(&at2, (void *)(0x666600000000));
+	ac_test_init(&at1, (void *)(0x123400000000), page_table_levels);
+	ac_test_init(&at2, (void *)(0x666600000000), page_table_levels);
 
 	at2.flags = AC_CPU_CR0_WP_MASK | AC_PDE_PSE_MASK | AC_PDE_PRESENT_MASK;
 	ac_test_setup_pte(&at2, pool);
@@ -850,12 +851,12 @@  err:
  * This test case is used to triger the bug which is fixed by
  * commit 3ddf6c06e13e in the kvm tree
  */
-static int check_pfec_on_prefetch_pte(ac_pool_t *pool)
+static int check_pfec_on_prefetch_pte(ac_pool_t *pool, int page_table_levels)
 {
 	ac_test_t at1, at2;
 
-	ac_test_init(&at1, (void *)(0x123406001000));
-	ac_test_init(&at2, (void *)(0x123406003000));
+	ac_test_init(&at1, (void *)(0x123406001000), page_table_levels);
+	ac_test_init(&at2, (void *)(0x123406003000), page_table_levels);
 
 	at1.flags = AC_PDE_PRESENT_MASK | AC_PTE_PRESENT_MASK;
 	ac_setup_specific_pages(&at1, pool, 30 * 1024 * 1024, 30 * 1024 * 1024);
@@ -895,12 +896,12 @@  err:
  *
  * Note: to trigger this bug, hugepage should be disabled on host.
  */
-static int check_large_pte_dirty_for_nowp(ac_pool_t *pool)
+static int check_large_pte_dirty_for_nowp(ac_pool_t *pool, int page_table_levels)
 {
 	ac_test_t at1, at2;
 
-	ac_test_init(&at1, (void *)(0x123403000000));
-	ac_test_init(&at2, (void *)(0x666606000000));
+	ac_test_init(&at1, (void *)(0x123403000000), page_table_levels);
+	ac_test_init(&at2, (void *)(0x666606000000), page_table_levels);
 
 	at2.flags = AC_PDE_PRESENT_MASK | AC_PDE_PSE_MASK;
 	ac_test_setup_pte(&at2, pool);
@@ -929,7 +930,7 @@  err:
 	return 0;
 }
 
-static int check_smep_andnot_wp(ac_pool_t *pool)
+static int check_smep_andnot_wp(ac_pool_t *pool, int page_table_levels)
 {
 	ac_test_t at1;
 	int err_prepare_andnot_wp, err_smep_andnot_wp;
@@ -938,7 +939,7 @@  static int check_smep_andnot_wp(ac_pool_t *pool)
 		return 1;
 	}
 
-	ac_test_init(&at1, (void *)(0x123406001000));
+	ac_test_init(&at1, (void *)(0x123406001000), page_table_levels);
 
 	at1.flags = AC_PDE_PRESENT_MASK | AC_PTE_PRESENT_MASK |
 		    AC_PDE_USER_MASK | AC_PTE_USER_MASK |
@@ -979,7 +980,7 @@  err:
 	return 0;
 }
 
-static int check_effective_sp_permissions(ac_pool_t *pool)
+static int check_effective_sp_permissions(ac_pool_t *pool, int page_table_levels)
 {
 	unsigned long ptr1 = 0x123480000000;
 	unsigned long ptr2 = ptr1 + SZ_2M;
@@ -1000,22 +1001,22 @@  static int check_effective_sp_permissions(ac_pool_t *pool)
 	 * pud1 and pud2 point to the same pmd page.
 	 */
 
-	ac_test_init(&at1, (void *)(ptr1));
+	ac_test_init(&at1, (void *)(ptr1), page_table_levels);
 	at1.flags = AC_PDE_PRESENT_MASK | AC_PTE_PRESENT_MASK |
 		    AC_PDE_USER_MASK | AC_PTE_USER_MASK |
 		    AC_PDE_ACCESSED_MASK | AC_PTE_ACCESSED_MASK |
 		    AC_PTE_WRITABLE_MASK | AC_ACCESS_USER_MASK;
 	__ac_setup_specific_pages(&at1, pool, false, pmd, 0);
 
-	ac_test_init(&at2, (void *)(ptr2));
+	ac_test_init(&at2, (void *)(ptr2), page_table_levels);
 	at2.flags = at1.flags | AC_PDE_WRITABLE_MASK | AC_PTE_DIRTY_MASK | AC_ACCESS_WRITE_MASK;
 	__ac_setup_specific_pages(&at2, pool, true, pmd, 0);
 
-	ac_test_init(&at3, (void *)(ptr3));
+	ac_test_init(&at3, (void *)(ptr3), page_table_levels);
 	at3.flags = AC_PDPTE_NO_WRITABLE_MASK | at1.flags;
 	__ac_setup_specific_pages(&at3, pool, true, pmd, 0);
 
-	ac_test_init(&at4, (void *)(ptr4));
+	ac_test_init(&at4, (void *)(ptr4), page_table_levels);
 	at4.flags = AC_PDPTE_NO_WRITABLE_MASK | at2.flags;
 	__ac_setup_specific_pages(&at4, pool, true, pmd, 0);
 
@@ -1058,7 +1059,7 @@  static int ac_test_exec(ac_test_t *at, ac_pool_t *pool)
 	return r;
 }
 
-typedef int (*ac_test_fn)(ac_pool_t *pool);
+typedef int (*ac_test_fn)(ac_pool_t *pool, int page_table_levels);
 const ac_test_fn ac_test_cases[] =
 {
 	corrupt_hugepage_triger,
@@ -1068,7 +1069,7 @@  const ac_test_fn ac_test_cases[] =
 	check_effective_sp_permissions,
 };
 
-int ac_test_run()
+int ac_test_run(int page_table_levels)
 {
 	ac_test_t at;
 	ac_pool_t pool;
@@ -1134,7 +1135,8 @@  int ac_test_run()
 	}
 
 	ac_env_int(&pool);
-	ac_test_init(&at, (void *)(0x123400000000 + 16 * smp_id()));
+	ac_test_init(&at, (void *)(0x123400000000 + 16 * smp_id()),
+		page_table_levels);
 	do {
 		++tests;
 		successes += ac_test_exec(&at, &pool);
@@ -1142,7 +1144,7 @@  int ac_test_run()
 
 	for (i = 0; i < ARRAY_SIZE(ac_test_cases); i++) {
 		++tests;
-		successes += ac_test_cases[i](&pool);
+		successes += ac_test_cases[i](&pool, page_table_levels);
 	}
 
 	printf("\n%d tests, %d failures\n", tests, tests - successes);
diff --git a/x86/access.h b/x86/access.h
index 4f67b62..bcfa7b2 100644
--- a/x86/access.h
+++ b/x86/access.h
@@ -1,8 +1,9 @@ 
 #ifndef X86_ACCESS_H
 #define X86_ACCESS_H
 
-int ac_test_run(void);
+#define PT_LEVEL_PML4 4
+#define PT_LEVEL_PML5 5
 
-extern int page_table_levels;
+int ac_test_run(int page_table_levels);
 
 #endif // X86_ACCESS_H
\ No newline at end of file
diff --git a/x86/access_test.c b/x86/access_test.c
index 497f286..991f333 100644
--- a/x86/access_test.c
+++ b/x86/access_test.c
@@ -8,14 +8,12 @@  int main(void)
     int r;
 
     printf("starting test\n\n");
-    page_table_levels = 4;
-    r = ac_test_run();
+    r = ac_test_run(PT_LEVEL_PML4);
 
     if (this_cpu_has(X86_FEATURE_LA57)) {
-        page_table_levels = 5;
         printf("starting 5-level paging test.\n\n");
         setup_5level_page_table();
-        r = ac_test_run();
+        r = ac_test_run(PT_LEVEL_PML5);
     }
 
     return r ? 0 : 1;