* [PATCH 1/3] KVM test: separate expect status updates from ac_test_setup_pte() function @ 2010-07-23 4:59 Xiao Guangrong 2010-07-23 5:03 ` [PATCH 2/3] KVM test: separate pool from ac_test_t struct Xiao Guangrong 2010-07-27 21:14 ` [PATCH 1/3] KVM test: separate expect status updates from ac_test_setup_pte() function Marcelo Tosatti 0 siblings, 2 replies; 4+ messages in thread From: Xiao Guangrong @ 2010-07-23 4:59 UTC (permalink / raw) To: Avi Kivity; +Cc: Marcelo Tosatti, KVM list Separate expect status updates operation, later we can just modify the access way(i,e the AC_ACCESS_* flags) Signed-off-by: Xiao Guangrong <xiaoguangrong@cn.fujitsu.com> --- kvm/test/x86/access.c | 131 ++++++++++++++++++++++++++----------------------- 1 files changed, 69 insertions(+), 62 deletions(-) diff --git a/kvm/test/x86/access.c b/kvm/test/x86/access.c index 3338fbc..c7d7e29 100644 --- a/kvm/test/x86/access.c +++ b/kvm/test/x86/access.c @@ -302,72 +302,12 @@ void ac_test_reset_pt_pool(ac_test_t *at) at->pt_pool_current = 0; } -void ac_test_setup_pte(ac_test_t *at) +void ac_set_expected_status(ac_test_t *at) { - unsigned long root = read_cr3(); int pde_valid, pte_valid; - if (!ac_test_enough_room(at)) - ac_test_reset_pt_pool(at); - - at->ptep = 0; - for (int i = 4; i >= 1 && (i >= 2 || !at->flags[AC_PDE_PSE]); --i) { - 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 = 0; - switch (i) { - case 4: - case 3: - pte = vroot[index]; - pte = ac_test_alloc_pt(at) | PT_PRESENT_MASK; - pte |= PT_WRITABLE_MASK | PT_USER_MASK; - break; - case 2: - if (!at->flags[AC_PDE_PSE]) - pte = ac_test_alloc_pt(at); - else { - pte = at->phys & PT_PSE_BASE_ADDR_MASK; - pte |= PT_PSE_MASK; - } - 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; - if (at->flags[AC_PDE_BIT51]) - pte |= 1ull << 51; - at->pdep = &vroot[index]; - break; - case 1: - pte = at->phys & PT_BASE_ADDR_MASK; - if (at->flags[AC_PTE_PRESENT]) - pte |= PT_PRESENT_MASK; - if (at->flags[AC_PTE_WRITABLE]) - pte |= PT_WRITABLE_MASK; - if (at->flags[AC_PTE_USER]) - pte |= PT_USER_MASK; - if (at->flags[AC_PTE_ACCESSED]) - pte |= PT_ACCESSED_MASK; - if (at->flags[AC_PTE_DIRTY]) - pte |= PT_DIRTY_MASK; - if (at->flags[AC_PTE_NX]) - pte |= PT_NX_MASK; - if (at->flags[AC_PTE_BIT51]) - pte |= 1ull << 51; - at->ptep = &vroot[index]; - break; - } - vroot[index] = pte; - root = vroot[index]; - } invlpg(at->virt); + if (at->ptep) at->expected_pte = *at->ptep; at->expected_pde = *at->pdep; @@ -467,6 +407,73 @@ fault: at->expected_error &= ~PFERR_FETCH_MASK; } +void ac_test_setup_pte(ac_test_t *at) +{ + unsigned long root = read_cr3(); + + if (!ac_test_enough_room(at)) + ac_test_reset_pt_pool(at); + + at->ptep = 0; + for (int i = 4; i >= 1 && (i >= 2 || !at->flags[AC_PDE_PSE]); --i) { + 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 = 0; + switch (i) { + case 4: + case 3: + pte = vroot[index]; + pte = ac_test_alloc_pt(at) | PT_PRESENT_MASK; + pte |= PT_WRITABLE_MASK | PT_USER_MASK; + break; + case 2: + if (!at->flags[AC_PDE_PSE]) + pte = ac_test_alloc_pt(at); + else { + pte = at->phys & PT_PSE_BASE_ADDR_MASK; + pte |= PT_PSE_MASK; + } + 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; + if (at->flags[AC_PDE_BIT51]) + pte |= 1ull << 51; + at->pdep = &vroot[index]; + break; + case 1: + pte = at->phys & PT_BASE_ADDR_MASK; + if (at->flags[AC_PTE_PRESENT]) + pte |= PT_PRESENT_MASK; + if (at->flags[AC_PTE_WRITABLE]) + pte |= PT_WRITABLE_MASK; + if (at->flags[AC_PTE_USER]) + pte |= PT_USER_MASK; + if (at->flags[AC_PTE_ACCESSED]) + pte |= PT_ACCESSED_MASK; + if (at->flags[AC_PTE_DIRTY]) + pte |= PT_DIRTY_MASK; + if (at->flags[AC_PTE_NX]) + pte |= PT_NX_MASK; + if (at->flags[AC_PTE_BIT51]) + pte |= 1ull << 51; + at->ptep = &vroot[index]; + break; + } + vroot[index] = pte; + root = vroot[index]; + } + ac_set_expected_status(at); +} + static void ac_test_check(ac_test_t *at, _Bool *success_ret, _Bool cond, const char *fmt, ...) { -- 1.6.1.2 ^ permalink raw reply related [flat|nested] 4+ messages in thread
* [PATCH 2/3] KVM test: separate pool from ac_test_t struct 2010-07-23 4:59 [PATCH 1/3] KVM test: separate expect status updates from ac_test_setup_pte() function Xiao Guangrong @ 2010-07-23 5:03 ` Xiao Guangrong 2010-07-23 5:07 ` [PATCH 3/3] KVM test: add test case to trigger the bug which cause hugepage mapping corrupt Xiao Guangrong 2010-07-27 21:14 ` [PATCH 1/3] KVM test: separate expect status updates from ac_test_setup_pte() function Marcelo Tosatti 1 sibling, 1 reply; 4+ messages in thread From: Xiao Guangrong @ 2010-07-23 5:03 UTC (permalink / raw) To: Avi Kivity; +Cc: Marcelo Tosatti, KVM list Separate pool from the ac_test_t struct, later we will use multiple ac_test_t units, those units should allocate pte from the same pool to avoid mapping to the same pte Signed-off-by: Xiao Guangrong <xiaoguangrong@cn.fujitsu.com> --- kvm/test/x86/access.c | 71 ++++++++++++++++++++++++++++-------------------- 1 files changed, 41 insertions(+), 30 deletions(-) diff --git a/kvm/test/x86/access.c b/kvm/test/x86/access.c index ebadae9..be51a55 100644 --- a/kvm/test/x86/access.c +++ b/kvm/test/x86/access.c @@ -127,12 +127,15 @@ typedef struct { } idt_entry_t; typedef struct { - unsigned flags[NR_AC_FLAGS]; - void *virt; - pt_element_t phys; pt_element_t pt_pool; unsigned pt_pool_size; unsigned pt_pool_current; +} ac_pool_t; + +typedef struct { + unsigned flags[NR_AC_FLAGS]; + void *virt; + pt_element_t phys; pt_element_t *ptep; pt_element_t expected_pte; pt_element_t *pdep; @@ -225,23 +228,29 @@ void set_efer_nx(int nx) wrmsr(MSR_EFER, efer); } +static void ac_env_int(ac_pool_t *pool) +{ + static idt_entry_t idt[256]; + + memset(idt, 0, sizeof(idt)); + lidt(idt, 256); + extern char page_fault, kernel_entry; + set_idt_entry(&idt[14], &page_fault, 0); + set_idt_entry(&idt[0x20], &kernel_entry, 3); -void ac_test_init(ac_test_t *at) + pool->pt_pool = 33 * 1024 * 1024; + pool->pt_pool_size = 120 * 1024 * 1024 - pool->pt_pool; + pool->pt_pool_current = 0; +} + +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->virt = (void *)(0x123400000000 + 16 * smp_id()); + at->virt = virt; at->phys = 32 * 1024 * 1024; - at->pt_pool = 33 * 1024 * 1024; - at->pt_pool_size = 120 * 1024 * 1024 - at->pt_pool; - at->pt_pool_current = 0; - memset(at->idt, 0, sizeof at->idt); - lidt(at->idt, 256); - extern char page_fault, kernel_entry; - set_idt_entry(&at->idt[14], &page_fault, 0); - set_idt_entry(&at->idt[0x20], &kernel_entry, 3); } int ac_test_bump_one(ac_test_t *at) @@ -285,21 +294,21 @@ void invlpg(void *addr) asm volatile ("invlpg (%0)" : : "r"(addr)); } -pt_element_t ac_test_alloc_pt(ac_test_t *at) +pt_element_t ac_test_alloc_pt(ac_pool_t *pool) { - pt_element_t ret = at->pt_pool + at->pt_pool_current; - at->pt_pool_current += PAGE_SIZE; + pt_element_t ret = pool->pt_pool + pool->pt_pool_current; + pool->pt_pool_current += PAGE_SIZE; return ret; } -_Bool ac_test_enough_room(ac_test_t *at) +_Bool ac_test_enough_room(ac_pool_t *pool) { - return at->pt_pool_current + 4 * PAGE_SIZE <= at->pt_pool_size; + return pool->pt_pool_current + 4 * PAGE_SIZE <= pool->pt_pool_size; } -void ac_test_reset_pt_pool(ac_test_t *at) +void ac_test_reset_pt_pool(ac_pool_t *pool) { - at->pt_pool_current = 0; + pool->pt_pool_current = 0; } void ac_set_expected_status(ac_test_t *at) @@ -407,12 +416,12 @@ fault: at->expected_error &= ~PFERR_FETCH_MASK; } -void ac_test_setup_pte(ac_test_t *at) +void ac_test_setup_pte(ac_test_t *at, ac_pool_t *pool) { unsigned long root = read_cr3(); - if (!ac_test_enough_room(at)) - ac_test_reset_pt_pool(at); + if (!ac_test_enough_room(pool)) + ac_test_reset_pt_pool(pool); at->ptep = 0; for (int i = 4; i >= 1 && (i >= 2 || !at->flags[AC_PDE_PSE]); --i) { @@ -423,12 +432,12 @@ void ac_test_setup_pte(ac_test_t *at) case 4: case 3: pte = vroot[index]; - pte = ac_test_alloc_pt(at) | PT_PRESENT_MASK; + pte = ac_test_alloc_pt(pool) | PT_PRESENT_MASK; pte |= PT_WRITABLE_MASK | PT_USER_MASK; break; case 2: if (!at->flags[AC_PDE_PSE]) - pte = ac_test_alloc_pt(at); + pte = ac_test_alloc_pt(pool); else { pte = at->phys & PT_PSE_BASE_ADDR_MASK; pte |= PT_PSE_MASK; @@ -620,29 +629,31 @@ static void ac_test_show(ac_test_t *at) printf("%s", line); } -int ac_test_exec(ac_test_t *at) +int ac_test_exec(ac_test_t *at, ac_pool_t *pool) { int r; if (verbose) { ac_test_show(at); } - ac_test_setup_pte(at); + ac_test_setup_pte(at, pool); r = ac_test_do_access(at); return r; } int ac_test_run(void) { - static ac_test_t at; + ac_test_t at; + ac_pool_t pool; int tests, successes; printf("run\n"); tests = successes = 0; - ac_test_init(&at); + ac_env_int(&pool); + ac_test_init(&at, (void *)(0x123400000000 + 16 * smp_id())); do { ++tests; - successes += ac_test_exec(&at); + successes += ac_test_exec(&at, &pool); } while (ac_test_bump(&at)); printf("\n%d tests, %d failures\n", tests, tests - successes); -- 1.6.1.2 ^ permalink raw reply related [flat|nested] 4+ messages in thread
* [PATCH 3/3] KVM test: add test case to trigger the bug which cause hugepage mapping corrupt 2010-07-23 5:03 ` [PATCH 2/3] KVM test: separate pool from ac_test_t struct Xiao Guangrong @ 2010-07-23 5:07 ` Xiao Guangrong 0 siblings, 0 replies; 4+ messages in thread From: Xiao Guangrong @ 2010-07-23 5:07 UTC (permalink / raw) To: Avi Kivity; +Cc: Marcelo Tosatti, KVM list The test case can trigger the bug that fixed by commit e09e90a5 in the kvm tree to avoid regression Signed-off-by: Xiao Guangrong <xiaoguangrong@cn.fujitsu.com> --- kvm/test/x86/access.c | 46 ++++++++++++++++++++++++++++++++++++++++++++++ 1 files changed, 46 insertions(+), 0 deletions(-) diff --git a/kvm/test/x86/access.c b/kvm/test/x86/access.c index be51a55..a833df5 100644 --- a/kvm/test/x86/access.c +++ b/kvm/test/x86/access.c @@ -629,6 +629,49 @@ static void ac_test_show(ac_test_t *at) printf("%s", line); } +/* + * 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) +{ + ac_test_t at1, at2; + + 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; + 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; + ac_test_setup_pte(&at1, pool); + if (!ac_test_do_access(&at1)) + goto err; + + at1.flags[AC_ACCESS_WRITE] = 1; + ac_set_expected_status(&at1); + if (!ac_test_do_access(&at1)) + goto err; + + at2.flags[AC_ACCESS_WRITE] = 1; + ac_set_expected_status(&at2); + if (!ac_test_do_access(&at2)) + goto err; + + return 1; + +err: + printf("corrupt_hugepage_triger test fail\n"); + return 0; +} + int ac_test_exec(ac_test_t *at, ac_pool_t *pool) { int r; @@ -656,6 +699,9 @@ int ac_test_run(void) successes += ac_test_exec(&at, &pool); } while (ac_test_bump(&at)); + ++tests; + successes += corrupt_hugepage_triger(&pool); + printf("\n%d tests, %d failures\n", tests, tests - successes); return successes == tests; -- 1.6.1.2 ^ permalink raw reply related [flat|nested] 4+ messages in thread
* Re: [PATCH 1/3] KVM test: separate expect status updates from ac_test_setup_pte() function 2010-07-23 4:59 [PATCH 1/3] KVM test: separate expect status updates from ac_test_setup_pte() function Xiao Guangrong 2010-07-23 5:03 ` [PATCH 2/3] KVM test: separate pool from ac_test_t struct Xiao Guangrong @ 2010-07-27 21:14 ` Marcelo Tosatti 1 sibling, 0 replies; 4+ messages in thread From: Marcelo Tosatti @ 2010-07-27 21:14 UTC (permalink / raw) To: Xiao Guangrong; +Cc: Avi Kivity, KVM list On Fri, Jul 23, 2010 at 12:59:49PM +0800, Xiao Guangrong wrote: > Separate expect status updates operation, later we can just modify the access > way(i,e the AC_ACCESS_* flags) > > Signed-off-by: Xiao Guangrong <xiaoguangrong@cn.fujitsu.com> > --- > kvm/test/x86/access.c | 131 ++++++++++++++++++++++++++----------------------- > 1 files changed, 69 insertions(+), 62 deletions(-) > Applied all 3, thanks. ^ permalink raw reply [flat|nested] 4+ messages in thread
end of thread, other threads:[~2010-07-27 21:22 UTC | newest] Thread overview: 4+ messages (download: mbox.gz follow: Atom feed -- links below jump to the message on this page -- 2010-07-23 4:59 [PATCH 1/3] KVM test: separate expect status updates from ac_test_setup_pte() function Xiao Guangrong 2010-07-23 5:03 ` [PATCH 2/3] KVM test: separate pool from ac_test_t struct Xiao Guangrong 2010-07-23 5:07 ` [PATCH 3/3] KVM test: add test case to trigger the bug which cause hugepage mapping corrupt Xiao Guangrong 2010-07-27 21:14 ` [PATCH 1/3] KVM test: separate expect status updates from ac_test_setup_pte() function Marcelo Tosatti
This is a public inbox, see mirroring instructions for how to clone and mirror all data and code used for this inbox