From: Avi Kivity <[EMAIL PROTECTED]> Signed-off-by: Avi Kivity <[EMAIL PROTECTED]>
diff --git a/user/test/x86/access.c b/user/test/x86/access.c index 0e6d455..008ec49 100644 --- a/user/test/x86/access.c +++ b/user/test/x86/access.c @@ -24,6 +24,7 @@ typedef unsigned long pt_element_t; #define PFERR_PRESENT_MASK (1U << 0) #define PFERR_WRITE_MASK (1U << 1) #define PFERR_USER_MASK (1U << 2) +#define PFERR_RESERVED_MASK (1U << 3) #define PFERR_FETCH_MASK (1U << 4) #define MSR_EFER 0xc0000080 @@ -41,6 +42,13 @@ enum { AC_PTE_DIRTY, AC_PTE_NX, + AC_PDE_PRESENT, + AC_PDE_WRITABLE, + AC_PDE_USER, + AC_PDE_ACCESSED, + AC_PDE_DIRTY, + AC_PDE_NX, + AC_ACCESS_USER, AC_ACCESS_WRITE, AC_ACCESS_FETCH, @@ -59,6 +67,12 @@ const char *ac_names[] = { [AC_PTE_USER] = "pte.user", [AC_PTE_DIRTY] = "pte.d", [AC_PTE_NX] = "pte.nx", + [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_PTE_NX] = "pte.nx", [AC_ACCESS_WRITE] = "write", [AC_ACCESS_USER] = "user", [AC_ACCESS_FETCH] = "fetch", @@ -105,6 +119,8 @@ typedef struct { pt_element_t pt_pool; pt_element_t *ptep; pt_element_t expected_pte; + pt_element_t *pdep; + pt_element_t expected_pde; int expected_fault; unsigned expected_error; idt_entry_t idt[256]; @@ -262,12 +278,31 @@ void ac_test_setup_pte(ac_test_t *at) pt_element_t *vroot = va(root & PT_BASE_ADDR_MASK); unsigned index = ((unsigned long)at->virt >> (12 + (i-1) * 9)) & 511; pt_element_t pte; - if (i != 1) { + switch (i) { + case 4: + case 3: pte = vroot[index]; if (!(pte & PT_PRESENT_MASK)) pte = ac_test_alloc_pt(at) | PT_PRESENT_MASK; pte |= PT_WRITABLE_MASK | PT_USER_MASK; - } else { + break; + case 2: + pte = ac_test_alloc_pt(at); + if (at->flags[AC_PDE_PRESENT]) + pte |= PT_PRESENT_MASK; + if (at->flags[AC_PDE_WRITABLE]) + pte |= PT_WRITABLE_MASK; + if (at->flags[AC_PDE_USER]) + pte |= PT_USER_MASK; + if (at->flags[AC_PDE_ACCESSED]) + pte |= PT_ACCESSED_MASK; + if (at->flags[AC_PDE_DIRTY]) + pte |= PT_DIRTY_MASK; + if (at->flags[AC_PDE_NX]) + pte |= PT_NX_MASK; + at->pdep = &vroot[index]; + break; + case 1: pte = at->phys & PT_BASE_ADDR_MASK; if (at->flags[AC_PTE_PRESENT]) pte |= PT_PRESENT_MASK; @@ -282,44 +317,72 @@ void ac_test_setup_pte(ac_test_t *at) if (at->flags[AC_PTE_NX]) pte |= PT_NX_MASK; at->ptep = &vroot[index]; + break; } vroot[index] = pte; root = vroot[index]; } invlpg(at->virt); at->expected_pte = *at->ptep; + at->expected_pde = *at->pdep; at->expected_fault = 0; - at->expected_error = 0; - if (!at->flags[AC_PTE_PRESENT]) - at->expected_fault = 1; - else - at->expected_error |= PFERR_PRESENT_MASK; + at->expected_error = PFERR_PRESENT_MASK; - if (at->flags[AC_ACCESS_USER]) { + if (at->flags[AC_ACCESS_USER]) at->expected_error |= PFERR_USER_MASK; - if (!at->flags[AC_PTE_USER]) - at->expected_fault = 1; - } - if (at->flags[AC_ACCESS_WRITE]) { + if (at->flags[AC_ACCESS_WRITE]) at->expected_error |= PFERR_WRITE_MASK; - if (!at->flags[AC_PTE_WRITABLE] - && (at->flags[AC_CPU_CR0_WP] || at->flags[AC_ACCESS_USER])) { - at->expected_fault = 1; - } else if (!at->expected_fault) { - at->expected_pte |= PT_DIRTY_MASK; - } - } - if (at->flags[AC_ACCESS_FETCH]) { + if (at->flags[AC_ACCESS_FETCH]) at->expected_error |= PFERR_FETCH_MASK; - if (at->flags[AC_PTE_NX]) - at->expected_fault = 1; + + if (!at->flags[AC_PDE_PRESENT]) { + at->expected_fault = 1; + at->expected_error &= ~PFERR_PRESENT_MASK; } - if (!at->expected_fault) { - at->expected_pte |= PT_ACCESSED_MASK; + if (at->flags[AC_ACCESS_USER] && !at->flags[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])) + at->expected_fault = 1; + + if (at->flags[AC_ACCESS_FETCH] && at->flags[AC_PDE_NX]) + at->expected_fault = 1; + + if (at->expected_fault) + goto fault; + + at->expected_pde |= PT_ACCESSED_MASK; + + if (!at->flags[AC_PTE_PRESENT]) { + at->expected_fault = 1; + at->expected_error &= ~PFERR_PRESENT_MASK; } + + if (at->flags[AC_ACCESS_USER] && !at->flags[AC_PTE_USER]) + at->expected_fault = 1; + + if (at->flags[AC_ACCESS_WRITE] + && !at->flags[AC_PTE_WRITABLE] + && (at->flags[AC_CPU_CR0_WP] || at->flags[AC_ACCESS_USER])) + at->expected_fault = 1; + + if (at->flags[AC_ACCESS_FETCH] && at->flags[AC_PTE_NX]) + at->expected_fault = 1; + + if (at->expected_fault) + goto fault; + + at->expected_pte |= PT_ACCESSED_MASK; + if (at->flags[AC_ACCESS_WRITE]) + at->expected_pte |= PT_DIRTY_MASK; + +fault: + ; } int ac_test_do_access(ac_test_t *at) @@ -401,6 +464,11 @@ int ac_test_do_access(ac_test_t *at) return 0; } + if (*at->pdep != at->expected_pde) { + printf("pde %x expected %x\n", *at->pdep, at->expected_pde); + return 0; + } + printf("OK\n"); return 1; } ------------------------------------------------------------------------- SF.Net email is sponsored by: Check out the new SourceForge.net Marketplace. It's the best place to buy or sell services for just about anything Open Source. http://sourceforge.net/services/buy/index.php _______________________________________________ kvm-commits mailing list kvm-commits@lists.sourceforge.net https://lists.sourceforge.net/lists/listinfo/kvm-commits