[PATCH kvm-unit-tests 03/13] x86: access: change flags from array to bitmask

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



This will make it possible to pass the flags by value and simplify
the implementation of the "twice" tests.

Signed-off-by: Paolo Bonzini <pbonzini@xxxxxxxxxx>
---
 x86/access.c | 398 ++++++++++++++++++++++++++++++-----------------------------
 1 file changed, 205 insertions(+), 193 deletions(-)

diff --git a/x86/access.c b/x86/access.c
index 311ebc1..966addc 100644
--- a/x86/access.c
+++ b/x86/access.c
@@ -49,69 +49,101 @@ static int cpuid_7_ecx;
  */
 
 enum {
-    AC_PTE_PRESENT,
-    AC_PTE_WRITABLE,
-    AC_PTE_USER,
-    AC_PTE_ACCESSED,
-    AC_PTE_DIRTY,
-    AC_PTE_NX,
-    AC_PTE_BIT51,
-
-    AC_PDE_PRESENT,
-    AC_PDE_WRITABLE,
-    AC_PDE_USER,
-    AC_PDE_ACCESSED,
-    AC_PDE_DIRTY,
-    AC_PDE_PSE,
-    AC_PDE_NX,
-    AC_PDE_BIT51,
-    AC_PDE_BIT13,
-
-    AC_PKU_AD,
-    AC_PKU_WD,
-    AC_PKU_PKEY,
-
-    AC_ACCESS_USER,
-    AC_ACCESS_WRITE,
-    AC_ACCESS_FETCH,
-    AC_ACCESS_TWICE,
-
-    AC_CPU_EFER_NX,
-    AC_CPU_CR0_WP,
-    AC_CPU_CR4_SMEP,
-    AC_CPU_CR4_PKE,
+    AC_PTE_PRESENT_BIT,
+    AC_PTE_WRITABLE_BIT,
+    AC_PTE_USER_BIT,
+    AC_PTE_ACCESSED_BIT,
+    AC_PTE_DIRTY_BIT,
+    AC_PTE_NX_BIT,
+    AC_PTE_BIT51_BIT,
+
+    AC_PDE_PRESENT_BIT,
+    AC_PDE_WRITABLE_BIT,
+    AC_PDE_USER_BIT,
+    AC_PDE_ACCESSED_BIT,
+    AC_PDE_DIRTY_BIT,
+    AC_PDE_PSE_BIT,
+    AC_PDE_NX_BIT,
+    AC_PDE_BIT51_BIT,
+    AC_PDE_BIT13_BIT,
+
+    AC_PKU_AD_BIT,
+    AC_PKU_WD_BIT,
+    AC_PKU_PKEY_BIT,
+
+    AC_ACCESS_USER_BIT,
+    AC_ACCESS_WRITE_BIT,
+    AC_ACCESS_FETCH_BIT,
+    AC_ACCESS_TWICE_BIT,
+
+    AC_CPU_EFER_NX_BIT,
+    AC_CPU_CR0_WP_BIT,
+    AC_CPU_CR4_SMEP_BIT,
+    AC_CPU_CR4_PKE_BIT,
 
     NR_AC_FLAGS
 };
 
+#define AC_PTE_PRESENT_MASK   (1 << AC_PTE_PRESENT_BIT)
+#define AC_PTE_WRITABLE_MASK  (1 << AC_PTE_WRITABLE_BIT)
+#define AC_PTE_USER_MASK      (1 << AC_PTE_USER_BIT)
+#define AC_PTE_ACCESSED_MASK  (1 << AC_PTE_ACCESSED_BIT)
+#define AC_PTE_DIRTY_MASK     (1 << AC_PTE_DIRTY_BIT)
+#define AC_PTE_NX_MASK        (1 << AC_PTE_NX_BIT)
+#define AC_PTE_BIT51_MASK     (1 << AC_PTE_BIT51_BIT)
+
+#define AC_PDE_PRESENT_MASK   (1 << AC_PDE_PRESENT_BIT)
+#define AC_PDE_WRITABLE_MASK  (1 << AC_PDE_WRITABLE_BIT)
+#define AC_PDE_USER_MASK      (1 << AC_PDE_USER_BIT)
+#define AC_PDE_ACCESSED_MASK  (1 << AC_PDE_ACCESSED_BIT)
+#define AC_PDE_DIRTY_MASK     (1 << AC_PDE_DIRTY_BIT)
+#define AC_PDE_PSE_MASK       (1 << AC_PDE_PSE_BIT)
+#define AC_PDE_NX_MASK        (1 << AC_PDE_NX_BIT)
+#define AC_PDE_BIT51_MASK     (1 << AC_PDE_BIT51_BIT)
+#define AC_PDE_BIT13_MASK     (1 << AC_PDE_BIT13_BIT)
+
+#define AC_PKU_AD_MASK        (1 << AC_PKU_AD_BIT)
+#define AC_PKU_WD_MASK        (1 << AC_PKU_WD_BIT)
+#define AC_PKU_PKEY_MASK      (1 << AC_PKU_PKEY_BIT)
+
+#define AC_ACCESS_USER_MASK   (1 << AC_ACCESS_USER_BIT)
+#define AC_ACCESS_WRITE_MASK  (1 << AC_ACCESS_WRITE_BIT)
+#define AC_ACCESS_FETCH_MASK  (1 << AC_ACCESS_FETCH_BIT)
+#define AC_ACCESS_TWICE_MASK  (1 << AC_ACCESS_TWICE_BIT)
+
+#define AC_CPU_EFER_NX_MASK   (1 << AC_CPU_EFER_NX_BIT)
+#define AC_CPU_CR0_WP_MASK    (1 << AC_CPU_CR0_WP_BIT)
+#define AC_CPU_CR4_SMEP_MASK  (1 << AC_CPU_CR4_SMEP_BIT)
+#define AC_CPU_CR4_PKE_MASK   (1 << AC_CPU_CR4_PKE_BIT)
+
 const char *ac_names[] = {
-    [AC_PTE_PRESENT] = "pte.p",
-    [AC_PTE_ACCESSED] = "pte.a",
-    [AC_PTE_WRITABLE] = "pte.rw",
-    [AC_PTE_USER] = "pte.user",
-    [AC_PTE_DIRTY] = "pte.d",
-    [AC_PTE_NX] = "pte.nx",
-    [AC_PTE_BIT51] = "pte.51",
-    [AC_PDE_PRESENT] = "pde.p",
-    [AC_PDE_ACCESSED] = "pde.a",
-    [AC_PDE_WRITABLE] = "pde.rw",
-    [AC_PDE_USER] = "pde.user",
-    [AC_PDE_DIRTY] = "pde.d",
-    [AC_PDE_PSE] = "pde.pse",
-    [AC_PDE_NX] = "pde.nx",
-    [AC_PDE_BIT51] = "pde.51",
-    [AC_PDE_BIT13] = "pde.13",
-    [AC_PKU_AD] = "pkru.ad",
-    [AC_PKU_WD] = "pkru.wd",
-    [AC_PKU_PKEY] = "pkey=1",
-    [AC_ACCESS_WRITE] = "write",
-    [AC_ACCESS_USER] = "user",
-    [AC_ACCESS_FETCH] = "fetch",
-    [AC_ACCESS_TWICE] = "twice",
-    [AC_CPU_EFER_NX] = "efer.nx",
-    [AC_CPU_CR0_WP] = "cr0.wp",
-    [AC_CPU_CR4_SMEP] = "cr4.smep",
-    [AC_CPU_CR4_PKE] = "cr4.pke",
+    [AC_PTE_PRESENT_BIT] = "pte.p",
+    [AC_PTE_ACCESSED_BIT] = "pte.a",
+    [AC_PTE_WRITABLE_BIT] = "pte.rw",
+    [AC_PTE_USER_BIT] = "pte.user",
+    [AC_PTE_DIRTY_BIT] = "pte.d",
+    [AC_PTE_NX_BIT] = "pte.nx",
+    [AC_PTE_BIT51_BIT] = "pte.51",
+    [AC_PDE_PRESENT_BIT] = "pde.p",
+    [AC_PDE_ACCESSED_BIT] = "pde.a",
+    [AC_PDE_WRITABLE_BIT] = "pde.rw",
+    [AC_PDE_USER_BIT] = "pde.user",
+    [AC_PDE_DIRTY_BIT] = "pde.d",
+    [AC_PDE_PSE_BIT] = "pde.pse",
+    [AC_PDE_NX_BIT] = "pde.nx",
+    [AC_PDE_BIT51_BIT] = "pde.51",
+    [AC_PDE_BIT13_BIT] = "pde.13",
+    [AC_PKU_AD_BIT] = "pkru.ad",
+    [AC_PKU_WD_BIT] = "pkru.wd",
+    [AC_PKU_PKEY_BIT] = "pkey=1",
+    [AC_ACCESS_WRITE_BIT] = "write",
+    [AC_ACCESS_USER_BIT] = "user",
+    [AC_ACCESS_FETCH_BIT] = "fetch",
+    [AC_ACCESS_TWICE_BIT] = "twice",
+    [AC_CPU_EFER_NX_BIT] = "efer.nx",
+    [AC_CPU_CR0_WP_BIT] = "cr0.wp",
+    [AC_CPU_CR4_SMEP_BIT] = "cr4.smep",
+    [AC_CPU_CR4_PKE_BIT] = "cr4.pke",
 };
 
 static inline void *va(pt_element_t phys)
@@ -126,7 +158,7 @@ typedef struct {
 } ac_pool_t;
 
 typedef struct {
-    unsigned flags[NR_AC_FLAGS];
+    unsigned flags;
     void *virt;
     pt_element_t phys;
     pt_element_t *ptep;
@@ -232,40 +264,36 @@ void ac_test_init(ac_test_t *at, void *virt)
 {
     wrmsr(MSR_EFER, rdmsr(MSR_EFER) | EFER_NX_MASK);
     set_cr0_wp(1);
-    for (int i = 0; i < NR_AC_FLAGS; ++i)
-	at->flags[i] = 0;
+    at->flags = 0;
     at->virt = virt;
     at->phys = 32 * 1024 * 1024;
 }
 
 int ac_test_bump_one(ac_test_t *at)
 {
-    for (int i = 0; i < NR_AC_FLAGS; ++i)
-	if (!at->flags[i]) {
-	    at->flags[i] = 1;
-	    return 1;
-	} else
-	    at->flags[i] = 0;
-    return 0;
+    at->flags++;
+    return at->flags < (1 << NR_AC_FLAGS);
 }
 
+#define F(x)  ((at->flags & x##_MASK) != 0)
+
 _Bool ac_test_legal(ac_test_t *at)
 {
-    if (at->flags[AC_ACCESS_FETCH] && at->flags[AC_ACCESS_WRITE])
+    if (F(AC_ACCESS_FETCH) && F(AC_ACCESS_WRITE))
 	return false;
 
     /*
      * Since we convert current page to kernel page when cr4.smep=1,
      * we can't switch to user mode.
      */
-    if (at->flags[AC_ACCESS_USER] && at->flags[AC_CPU_CR4_SMEP])
+    if (F(AC_ACCESS_USER) && F(AC_CPU_CR4_SMEP))
 	return false;
 
     /*
      * Only test protection key faults if CR4.PKE=1.
      */
-    if (!at->flags[AC_CPU_CR4_PKE] &&
-        (at->flags[AC_PKU_AD] || at->flags[AC_PKU_WD])) {
+    if (!F(AC_CPU_CR4_PKE) &&
+        (F(AC_PKU_AD) || F(AC_PKU_WD))) {
 	return false;
     }
 
@@ -273,7 +301,7 @@ _Bool ac_test_legal(ac_test_t *at)
      * pde.bit13 checks handling of reserved bits in largepage PDEs.  It is
      * meaningless if there is a PTE.
      */
-    if (!at->flags[AC_PDE_PSE] && at->flags[AC_PDE_BIT13])
+    if (!F(AC_PDE_PSE) && F(AC_PDE_BIT13))
         return false;
 
     return true;
@@ -319,24 +347,24 @@ void ac_set_expected_status(ac_test_t *at)
     at->expected_fault = 0;
     at->expected_error = PFERR_PRESENT_MASK;
 
-    pde_valid = at->flags[AC_PDE_PRESENT]
-        && !at->flags[AC_PDE_BIT51] && !at->flags[AC_PDE_BIT13]
-        && !(at->flags[AC_PDE_NX] && !at->flags[AC_CPU_EFER_NX]);
+    pde_valid = F(AC_PDE_PRESENT)
+        && !F(AC_PDE_BIT51) && !F(AC_PDE_BIT13)
+        && !(F(AC_PDE_NX) && !F(AC_CPU_EFER_NX));
     pte_valid = pde_valid
-        && at->flags[AC_PTE_PRESENT]
-        && !at->flags[AC_PTE_BIT51]
-        && !(at->flags[AC_PTE_NX] && !at->flags[AC_CPU_EFER_NX]);
+        && F(AC_PTE_PRESENT)
+        && !F(AC_PTE_BIT51)
+        && !(F(AC_PTE_NX) && !F(AC_CPU_EFER_NX));
 
-    if (at->flags[AC_ACCESS_USER])
+    if (F(AC_ACCESS_USER))
 	at->expected_error |= PFERR_USER_MASK;
 
-    if (at->flags[AC_ACCESS_WRITE])
+    if (F(AC_ACCESS_WRITE))
 	at->expected_error |= PFERR_WRITE_MASK;
 
-    if (at->flags[AC_ACCESS_FETCH])
+    if (F(AC_ACCESS_FETCH))
 	at->expected_error |= PFERR_FETCH_MASK;
 
-    if (!at->flags[AC_PDE_PRESENT]) {
+    if (!F(AC_PDE_PRESENT)) {
 	at->expected_fault = 1;
 	at->expected_error &= ~PFERR_PRESENT_MASK;
     } else if (!pde_valid) {
@@ -344,18 +372,18 @@ void ac_set_expected_status(ac_test_t *at)
         at->expected_error |= PFERR_RESERVED_MASK;
     }
 
-    if (at->flags[AC_ACCESS_USER] && !at->flags[AC_PDE_USER])
+    if (F(AC_ACCESS_USER) && !F(AC_PDE_USER))
 	at->expected_fault = 1;
 
-    if (at->flags[AC_ACCESS_WRITE]
-	&& !at->flags[AC_PDE_WRITABLE]
-	&& (at->flags[AC_CPU_CR0_WP] || at->flags[AC_ACCESS_USER]))
+    if (F(AC_ACCESS_WRITE)
+	&& !F(AC_PDE_WRITABLE)
+	&& (F(AC_CPU_CR0_WP) || F(AC_ACCESS_USER)))
 	at->expected_fault = 1;
 
-    if (at->flags[AC_ACCESS_FETCH] && at->flags[AC_PDE_NX])
+    if (F(AC_ACCESS_FETCH) && F(AC_PDE_NX))
 	at->expected_fault = 1;
 
-    if (!at->flags[AC_PDE_ACCESSED])
+    if (!F(AC_PDE_ACCESSED))
         at->ignore_pde = PT_ACCESSED_MASK;
 
     if (!pde_valid)
@@ -364,37 +392,37 @@ void ac_set_expected_status(ac_test_t *at)
     if (!at->expected_fault)
         at->expected_pde |= PT_ACCESSED_MASK;
 
-    if (at->flags[AC_PDE_PSE]) {
+    if (F(AC_PDE_PSE)) {
         /* Even for "twice" accesses, PKEY might cause pde.a=0.  */
-        if (at->flags[AC_PDE_USER] && at->flags[AC_ACCESS_TWICE] &&
-            at->flags[AC_PKU_PKEY] && at->flags[AC_CPU_CR4_PKE] &&
-            at->flags[AC_PKU_AD]) {
+        if (F(AC_PDE_USER) && F(AC_ACCESS_TWICE) &&
+            F(AC_PKU_PKEY) && F(AC_CPU_CR4_PKE) &&
+            F(AC_PKU_AD)) {
             pde_valid = false;
         }
 
-	if (at->flags[AC_ACCESS_FETCH] && at->flags[AC_PDE_USER]
-	    && at->flags[AC_CPU_CR4_SMEP])
+	if (F(AC_ACCESS_FETCH) && F(AC_PDE_USER)
+	    && F(AC_CPU_CR4_SMEP))
 	    at->expected_fault = 1;
 
-        if (at->flags[AC_PDE_USER] && !at->flags[AC_ACCESS_FETCH] &&
-	    at->flags[AC_PKU_PKEY] && at->flags[AC_CPU_CR4_PKE] &&
+        if (F(AC_PDE_USER) && !F(AC_ACCESS_FETCH) &&
+	    F(AC_PKU_PKEY) && F(AC_CPU_CR4_PKE) &&
 	    !at->expected_fault) {
-            if (at->flags[AC_PKU_AD]) {
+            if (F(AC_PKU_AD)) {
                 at->expected_fault = 1;
                 at->expected_error |= PFERR_PK_MASK;
-            } else if (at->flags[AC_ACCESS_WRITE] && at->flags[AC_PKU_WD] &&
-                       (at->flags[AC_CPU_CR0_WP] || at->flags[AC_ACCESS_USER])) {
+            } else if (F(AC_ACCESS_WRITE) && F(AC_PKU_WD) &&
+                       (F(AC_CPU_CR0_WP) || F(AC_ACCESS_USER))) {
                 at->expected_fault = 1;
                 at->expected_error |= PFERR_PK_MASK;
             }
         }
-	if (at->flags[AC_ACCESS_WRITE] && !at->expected_fault)
+	if (F(AC_ACCESS_WRITE) && !at->expected_fault)
 	    at->expected_pde |= PT_DIRTY_MASK;
 
 	goto no_pte;
     }
 
-    if (!at->flags[AC_PTE_PRESENT]) {
+    if (!F(AC_PTE_PRESENT)) {
 	at->expected_fault = 1;
 	at->expected_error &= ~PFERR_PRESENT_MASK;
     } else if (!pte_valid) {
@@ -402,39 +430,39 @@ void ac_set_expected_status(ac_test_t *at)
         at->expected_error |= PFERR_RESERVED_MASK;
     }
 
-    if (at->flags[AC_ACCESS_USER] && !at->flags[AC_PTE_USER])
+    if (F(AC_ACCESS_USER) && !F(AC_PTE_USER))
 	at->expected_fault = 1;
 
     if (!pte_valid)
         goto fault;
 
     /* Even for "twice" accesses, PKEY might cause pte.a=0.  */
-    if (at->flags[AC_PDE_USER] && at->flags[AC_PTE_USER] && at->flags[AC_ACCESS_TWICE] &&
-        at->flags[AC_PKU_PKEY] && at->flags[AC_CPU_CR4_PKE] &&
-	at->flags[AC_PKU_AD]) {
+    if (F(AC_PDE_USER) && F(AC_PTE_USER) && F(AC_ACCESS_TWICE) &&
+        F(AC_PKU_PKEY) && F(AC_CPU_CR4_PKE) &&
+	F(AC_PKU_AD)) {
         pte_valid = false;
     }
 
-    if (at->flags[AC_ACCESS_WRITE]
-	&& !at->flags[AC_PTE_WRITABLE]
-	&& (at->flags[AC_CPU_CR0_WP] || at->flags[AC_ACCESS_USER]))
+    if (F(AC_ACCESS_WRITE)
+	&& !F(AC_PTE_WRITABLE)
+	&& (F(AC_CPU_CR0_WP) || F(AC_ACCESS_USER)))
 	at->expected_fault = 1;
 
-    if (at->flags[AC_ACCESS_FETCH]
-	&& (at->flags[AC_PTE_NX]
-	    || (at->flags[AC_CPU_CR4_SMEP]
-		&& at->flags[AC_PDE_USER]
-		&& at->flags[AC_PTE_USER])))
+    if (F(AC_ACCESS_FETCH)
+	&& (F(AC_PTE_NX)
+	    || (F(AC_CPU_CR4_SMEP)
+		&& F(AC_PDE_USER)
+		&& F(AC_PTE_USER))))
 	at->expected_fault = 1;
 
-    if (at->flags[AC_PDE_USER] && at->flags[AC_PTE_USER] && !at->flags[AC_ACCESS_FETCH] &&
-        at->flags[AC_PKU_PKEY] && at->flags[AC_CPU_CR4_PKE] &&
+    if (F(AC_PDE_USER) && F(AC_PTE_USER) && !F(AC_ACCESS_FETCH) &&
+        F(AC_PKU_PKEY) && F(AC_CPU_CR4_PKE) &&
 	!at->expected_fault) {
-        if (at->flags[AC_PKU_AD]) {
+        if (F(AC_PKU_AD)) {
             at->expected_fault = 1;
             at->expected_error |= PFERR_PK_MASK;
-        } else if (at->flags[AC_ACCESS_WRITE] && at->flags[AC_PKU_WD] &&
-                   (at->flags[AC_CPU_CR0_WP] || at->flags[AC_ACCESS_USER])) {
+        } else if (F(AC_ACCESS_WRITE) && F(AC_PKU_WD) &&
+                   (F(AC_CPU_CR0_WP) || F(AC_ACCESS_USER))) {
             at->expected_fault = 1;
             at->expected_error |= PFERR_PK_MASK;
         }
@@ -444,12 +472,12 @@ void ac_set_expected_status(ac_test_t *at)
 	goto fault;
 
     at->expected_pte |= PT_ACCESSED_MASK;
-    if (at->flags[AC_ACCESS_WRITE])
+    if (F(AC_ACCESS_WRITE))
 	at->expected_pte |= PT_DIRTY_MASK;
 
 no_pte:
 fault:
-    if (at->flags[AC_ACCESS_TWICE]) {
+    if (F(AC_ACCESS_TWICE)) {
 	if (pde_valid) {
 	    at->expected_pde |= PT_ACCESSED_MASK;
 	    if (pte_valid)
@@ -458,7 +486,7 @@ fault:
     }
     if (!at->expected_fault)
         at->ignore_pde = 0;
-    if (!at->flags[AC_CPU_EFER_NX] && !at->flags[AC_CPU_CR4_SMEP])
+    if (!F(AC_CPU_EFER_NX) && !F(AC_CPU_CR4_SMEP))
         at->expected_error &= ~PFERR_FETCH_MASK;
 }
 
@@ -472,7 +500,7 @@ void __ac_setup_specific_pages(ac_test_t *at, ac_pool_t *pool, u64 pd_page,
 	ac_test_reset_pt_pool(pool);
 
     at->ptep = 0;
-    for (int i = 4; i >= 1 && (i >= 2 || !at->flags[AC_PDE_PSE]); --i) {
+    for (int i = 4; 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;
@@ -483,52 +511,52 @@ void __ac_setup_specific_pages(ac_test_t *at, ac_pool_t *pool, u64 pd_page,
 	    pte |= PT_PRESENT_MASK | PT_WRITABLE_MASK | PT_USER_MASK;
 	    break;
 	case 2:
-	    if (!at->flags[AC_PDE_PSE]) {
+	    if (!F(AC_PDE_PSE)) {
 		pte = pt_page ? pt_page : ac_test_alloc_pt(pool);
 		/* The protection key is ignored on non-leaf entries.  */
-                if (at->flags[AC_PKU_PKEY])
+                if (F(AC_PKU_PKEY))
                     pte |= 2ull << 59;
 	    } else {
 		pte = at->phys & PT_PSE_BASE_ADDR_MASK;
 		pte |= PT_PSE_MASK;
-                if (at->flags[AC_PKU_PKEY])
+                if (F(AC_PKU_PKEY))
                     pte |= 1ull << 59;
 	    }
-	    if (at->flags[AC_PDE_PRESENT])
+	    if (F(AC_PDE_PRESENT))
 		pte |= PT_PRESENT_MASK;
-	    if (at->flags[AC_PDE_WRITABLE])
+	    if (F(AC_PDE_WRITABLE))
 		pte |= PT_WRITABLE_MASK;
-	    if (at->flags[AC_PDE_USER])
+	    if (F(AC_PDE_USER))
 		pte |= PT_USER_MASK;
-	    if (at->flags[AC_PDE_ACCESSED])
+	    if (F(AC_PDE_ACCESSED))
 		pte |= PT_ACCESSED_MASK;
-	    if (at->flags[AC_PDE_DIRTY])
+	    if (F(AC_PDE_DIRTY))
 		pte |= PT_DIRTY_MASK;
-	    if (at->flags[AC_PDE_NX])
+	    if (F(AC_PDE_NX))
 		pte |= PT_NX_MASK;
-	    if (at->flags[AC_PDE_BIT51])
+	    if (F(AC_PDE_BIT51))
 		pte |= 1ull << 51;
-	    if (at->flags[AC_PDE_BIT13])
+	    if (F(AC_PDE_BIT13))
 		pte |= 1ull << 13;
 	    at->pdep = &vroot[index];
 	    break;
 	case 1:
 	    pte = at->phys & PT_BASE_ADDR_MASK;
-	    if (at->flags[AC_PKU_PKEY])
+	    if (F(AC_PKU_PKEY))
 		pte |= 1ull << 59;
-	    if (at->flags[AC_PTE_PRESENT])
+	    if (F(AC_PTE_PRESENT))
 		pte |= PT_PRESENT_MASK;
-	    if (at->flags[AC_PTE_WRITABLE])
+	    if (F(AC_PTE_WRITABLE))
 		pte |= PT_WRITABLE_MASK;
-	    if (at->flags[AC_PTE_USER])
+	    if (F(AC_PTE_USER))
 		pte |= PT_USER_MASK;
-	    if (at->flags[AC_PTE_ACCESSED])
+	    if (F(AC_PTE_ACCESSED))
 		pte |= PT_ACCESSED_MASK;
-	    if (at->flags[AC_PTE_DIRTY])
+	    if (F(AC_PTE_DIRTY))
 		pte |= PT_DIRTY_MASK;
-	    if (at->flags[AC_PTE_NX])
+	    if (F(AC_PTE_NX))
 		pte |= PT_NX_MASK;
-	    if (at->flags[AC_PTE_BIT51])
+	    if (F(AC_PTE_BIT51))
 		pte |= 1ull << 51;
 	    at->ptep = &vroot[index];
 	    break;
@@ -556,7 +584,7 @@ static void dump_mapping(ac_test_t *at)
 	int i;
 
 	printf("Dump mapping: address: %p\n", at->virt);
-	for (i = 4; i >= 1 && (i >= 2 || !at->flags[AC_PDE_PSE]); --i) {
+	for (i = 4; 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];
@@ -614,16 +642,16 @@ int ac_test_do_access(ac_test_t *at)
     *((unsigned char *)at->phys) = 0xc3; /* ret */
 
     unsigned r = unique;
-    set_cr0_wp(at->flags[AC_CPU_CR0_WP]);
-    set_efer_nx(at->flags[AC_CPU_EFER_NX]);
-    if (at->flags[AC_CPU_CR4_PKE] && !(cpuid_7_ecx & (1 << 3))) {
+    set_cr0_wp(F(AC_CPU_CR0_WP));
+    set_efer_nx(F(AC_CPU_EFER_NX));
+    if (F(AC_CPU_CR4_PKE) && !(cpuid_7_ecx & (1 << 3))) {
 	unsigned long cr4 = read_cr4();
 	if (write_cr4_checking(cr4 | X86_CR4_PKE) == GP_VECTOR)
 		goto done;
 	printf("Set PKE in CR4 - expect #GP: FAIL!\n");
 	return 0;
     }
-    if (at->flags[AC_CPU_CR4_SMEP] && !(cpuid_7_ebx & (1 << 7))) {
+    if (F(AC_CPU_CR4_SMEP) && !(cpuid_7_ebx & (1 << 7))) {
 	unsigned long cr4 = read_cr4();
 	if (write_cr4_checking(cr4 | CR4_SMEP_MASK) == GP_VECTOR)
 		goto done;
@@ -631,16 +659,16 @@ int ac_test_do_access(ac_test_t *at)
 	return 0;
     }
 
-    set_cr4_pke(at->flags[AC_CPU_CR4_PKE]);
-    if (at->flags[AC_CPU_CR4_PKE]) {
-        /* WD2=AD2=1, WD1=at->flags[AC_PKU_WD], AD1=at->flags[AC_PKU_AD] */
-        write_pkru(0x30 | (at->flags[AC_PKU_WD] ? 8 : 0) |
-                   (at->flags[AC_PKU_AD] ? 4 : 0));
+    set_cr4_pke(F(AC_CPU_CR4_PKE));
+    if (F(AC_CPU_CR4_PKE)) {
+        /* WD2=AD2=1, WD1=F(AC_PKU_WD), AD1=F(AC_PKU_AD) */
+        write_pkru(0x30 | (F(AC_PKU_WD) ? 8 : 0) |
+                   (F(AC_PKU_AD) ? 4 : 0));
     }
 
-    set_cr4_smep(at->flags[AC_CPU_CR4_SMEP]);
+    set_cr4_smep(F(AC_CPU_CR4_SMEP));
 
-    if (at->flags[AC_ACCESS_TWICE]) {
+    if (F(AC_ACCESS_TWICE)) {
 	asm volatile (
 	    "mov $fixed2, %%rsi \n\t"
 	    "mov (%[addr]), %[reg] \n\t"
@@ -679,9 +707,9 @@ int ac_test_do_access(ac_test_t *at)
 		  "back_to_kernel:"
 		  : [reg]"+r"(r), "+a"(fault), "=b"(e), "=&d"(rsp)
 		  : [addr]"r"(at->virt),
-		    [write]"r"(at->flags[AC_ACCESS_WRITE]),
-		    [user]"r"(at->flags[AC_ACCESS_USER]),
-		    [fetch]"r"(at->flags[AC_ACCESS_FETCH]),
+		    [write]"r"(F(AC_ACCESS_WRITE)),
+		    [user]"r"(F(AC_ACCESS_USER)),
+		    [fetch]"r"(F(AC_ACCESS_FETCH)),
 		    [user_ds]"i"(USER_DS),
 		    [user_cs]"i"(USER_CS),
 		    [user_stack_top]"r"(user_stack + sizeof user_stack),
@@ -728,7 +756,7 @@ static void ac_test_show(ac_test_t *at)
     *line = 0;
     strcat(line, "test");
     for (int i = 0; i < NR_AC_FLAGS; ++i)
-	if (at->flags[i]) {
+	if (at->flags & (1 << i)) {
 	    strcat(line, " ");
 	    strcat(line, ac_names[i]);
 	}
@@ -747,27 +775,22 @@ static int corrupt_hugepage_triger(ac_pool_t *pool)
     ac_test_init(&at1, (void *)(0x123400000000));
     ac_test_init(&at2, (void *)(0x666600000000));
 
-    at2.flags[AC_CPU_CR0_WP] = 1;
-    at2.flags[AC_PDE_PSE] = 1;
-    at2.flags[AC_PDE_PRESENT] = 1;
+    at2.flags = AC_CPU_CR0_WP_MASK | AC_PDE_PSE_MASK | AC_PDE_PRESENT_MASK;
     ac_test_setup_pte(&at2, pool);
     if (!ac_test_do_access(&at2))
         goto err;
 
-    at1.flags[AC_CPU_CR0_WP] = 1;
-    at1.flags[AC_PDE_PSE] = 1;
-    at1.flags[AC_PDE_WRITABLE] = 1;
-    at1.flags[AC_PDE_PRESENT] = 1;
+    at1.flags = at2.flags | AC_PDE_WRITABLE_MASK;
     ac_test_setup_pte(&at1, pool);
     if (!ac_test_do_access(&at1))
         goto err;
 
-    at1.flags[AC_ACCESS_WRITE] = 1;
+    at1.flags |= AC_ACCESS_WRITE_MASK;
     ac_set_expected_status(&at1);
     if (!ac_test_do_access(&at1))
         goto err;
 
-    at2.flags[AC_ACCESS_WRITE] = 1;
+    at2.flags |= AC_ACCESS_WRITE_MASK;
     ac_set_expected_status(&at2);
     if (!ac_test_do_access(&at2))
         goto err;
@@ -790,13 +813,10 @@ static int check_pfec_on_prefetch_pte(ac_pool_t *pool)
 	ac_test_init(&at1, (void *)(0x123406001000));
 	ac_test_init(&at2, (void *)(0x123406003000));
 
-	at1.flags[AC_PDE_PRESENT] = 1;
-	at1.flags[AC_PTE_PRESENT] = 1;
+	at1.flags = AC_PDE_PRESENT_MASK | AC_PTE_PRESENT_MASK;
 	ac_setup_specific_pages(&at1, pool, 30 * 1024 * 1024, 30 * 1024 * 1024);
 
-	at2.flags[AC_PDE_PRESENT] = 1;
-	at2.flags[AC_PTE_NX] = 1;
-	at2.flags[AC_PTE_PRESENT] = 1;
+        at2.flags = at1.flags | AC_PTE_NX_MASK;
 	ac_setup_specific_pages(&at2, pool, 30 * 1024 * 1024, 30 * 1024 * 1024);
 
 	if (!ac_test_do_access(&at1)) {
@@ -838,26 +858,21 @@ static int check_large_pte_dirty_for_nowp(ac_pool_t *pool)
 	ac_test_init(&at1, (void *)(0x123403000000));
 	ac_test_init(&at2, (void *)(0x666606000000));
 
-	at2.flags[AC_PDE_PRESENT] = 1;
-	at2.flags[AC_PDE_PSE] = 1;
-
+        at2.flags = AC_PDE_PRESENT_MASK | AC_PDE_PSE_MASK;
 	ac_test_setup_pte(&at2, pool);
 	if (!ac_test_do_access(&at2)) {
 		printf("%s: read on the first mapping fail.\n", __FUNCTION__);
 		goto err;
 	}
 
-	at1.flags[AC_PDE_PRESENT] = 1;
-	at1.flags[AC_PDE_PSE] = 1;
-	at1.flags[AC_ACCESS_WRITE] = 1;
-
+        at1.flags = at2.flags | AC_ACCESS_WRITE_MASK;
 	ac_test_setup_pte(&at1, pool);
 	if (!ac_test_do_access(&at1)) {
 		printf("%s: write on the second mapping fail.\n", __FUNCTION__);
 		goto err;
 	}
 
-	at2.flags[AC_ACCESS_WRITE] = 1;
+	at2.flags |= AC_ACCESS_WRITE_MASK;
 	ac_set_expected_status(&at2);
 	if (!ac_test_do_access(&at2)) {
 		printf("%s: write on the first mapping fail.\n", __FUNCTION__);
@@ -877,15 +892,12 @@ static int check_smep_andnot_wp(ac_pool_t *pool)
 
 	ac_test_init(&at1, (void *)(0x123406001000));
 
-	at1.flags[AC_PDE_PRESENT] = 1;
-	at1.flags[AC_PTE_PRESENT] = 1;
-	at1.flags[AC_PDE_USER] = 1;
-	at1.flags[AC_PTE_USER] = 1;
-	at1.flags[AC_PDE_ACCESSED] = 1;
-	at1.flags[AC_PTE_ACCESSED] = 1;
-	at1.flags[AC_CPU_CR4_SMEP] = 1;
-	at1.flags[AC_CPU_CR0_WP] = 0;
-	at1.flags[AC_ACCESS_WRITE] = 1;
+	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_CPU_CR4_SMEP_MASK |
+            AC_CPU_CR0_WP_MASK |
+            AC_ACCESS_WRITE_MASK;
 	ac_test_setup_pte(&at1, pool);
 
 	/*
@@ -899,10 +911,10 @@ static int check_smep_andnot_wp(ac_pool_t *pool)
 		goto clean_up;
 	}
 
-	at1.flags[AC_ACCESS_WRITE] = 0;
-	at1.flags[AC_ACCESS_FETCH] = 1;
-	ac_set_expected_status(&at1);
-	err_smep_andnot_wp = ac_test_do_access(&at1);
+        at1.flags &= ~AC_ACCESS_WRITE_MASK;
+        at1.flags |= AC_ACCESS_FETCH_MASK;
+        ac_set_expected_status(&at1);
+        err_smep_andnot_wp = ac_test_do_access(&at1);
 
 clean_up:
 	set_cr4_smep(0);
-- 
2.5.0


--
To unsubscribe from this list: send the line "unsubscribe kvm" in
the body of a message to majordomo@xxxxxxxxxxxxxxx
More majordomo info at  http://vger.kernel.org/majordomo-info.html



[Index of Archives]     [KVM ARM]     [KVM ia64]     [KVM ppc]     [Virtualization Tools]     [Spice Development]     [Libvirt]     [Libvirt Users]     [Linux USB Devel]     [Linux Audio Users]     [Yosemite Questions]     [Linux Kernel]     [Linux SCSI]     [XFree86]
  Powered by Linux