* [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