[PATCH] kvm: testsuite: test EFER.NXE

2009-03-31 Thread Avi Kivity
From: Avi Kivity a...@redhat.com

Accesses with the NX bit set in a pte or pde behave differently when EFER.NXE
is set or unset.  Test that.

Signed-off-by: Avi Kivity a...@redhat.com

diff --git a/user/test/x86/access.c b/user/test/x86/access.c
index 59a5756..272a4ef 100644
--- a/user/test/x86/access.c
+++ b/user/test/x86/access.c
@@ -60,7 +60,7 @@ enum {
 AC_ACCESS_TWICE,
 // AC_ACCESS_PTE,
 
-// AC_CPU_EFER_NX,
+AC_CPU_EFER_NX,
 AC_CPU_CR0_WP,
 
 NR_AC_FLAGS
@@ -86,6 +86,7 @@ const char *ac_names[] = {
 [AC_ACCESS_USER] = user,
 [AC_ACCESS_FETCH] = fetch,
 [AC_ACCESS_TWICE] = twice,
+[AC_CPU_EFER_NX] = efer.nx,
 [AC_CPU_CR0_WP] = cr0.wp,
 };
 
@@ -367,10 +368,12 @@ void ac_test_setup_pte(ac_test_t *at)
 at-expected_error = PFERR_PRESENT_MASK;
 
 pde_valid = at-flags[AC_PDE_PRESENT]
- !at-flags[AC_PDE_BIT51];
+ !at-flags[AC_PDE_BIT51]
+ !(at-flags[AC_PDE_NX]  !at-flags[AC_CPU_EFER_NX]);
 pte_valid = pde_valid
  at-flags[AC_PTE_PRESENT]
- !at-flags[AC_PTE_BIT51];
+ !at-flags[AC_PTE_BIT51]
+ !(at-flags[AC_PTE_NX]  !at-flags[AC_CPU_EFER_NX]);
 if (at-flags[AC_ACCESS_TWICE]) {
if (pde_valid) {
at-expected_pde |= PT_ACCESSED_MASK;
@@ -463,6 +466,7 @@ int ac_test_do_access(ac_test_t *at)
 
 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_ACCESS_TWICE]) {
asm volatile (
--
To unsubscribe from this list: send the line unsubscribe kvm-commits in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[PATCH] kvm: testsuite: test reserved bits in mmu access tests

2009-03-31 Thread Avi Kivity
From: Avi Kivity a...@redhat.com

test that reserved bits in pdes and ptes cause faults and that the
expected error code is issued.

Signed-off-by: Avi Kivity a...@redhat.com

diff --git a/user/test/x86/access.c b/user/test/x86/access.c
index 49f74b3..59a5756 100644
--- a/user/test/x86/access.c
+++ b/user/test/x86/access.c
@@ -43,6 +43,7 @@ enum {
 AC_PTE_ACCESSED,
 AC_PTE_DIRTY,
 AC_PTE_NX,
+AC_PTE_BIT51,
 
 AC_PDE_PRESENT,
 AC_PDE_WRITABLE,
@@ -51,6 +52,7 @@ enum {
 AC_PDE_DIRTY,
 AC_PDE_PSE,
 AC_PDE_NX,
+AC_PDE_BIT51,
 
 AC_ACCESS_USER,
 AC_ACCESS_WRITE,
@@ -71,6 +73,7 @@ const char *ac_names[] = {
 [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,
@@ -78,6 +81,7 @@ const char *ac_names[] = {
 [AC_PDE_DIRTY] = pde.d,
 [AC_PDE_PSE] = pde.pse,
 [AC_PDE_NX] = pde.nx,
+[AC_PDE_BIT51] = pde.51,
 [AC_ACCESS_WRITE] = write,
 [AC_ACCESS_USER] = user,
 [AC_ACCESS_FETCH] = fetch,
@@ -293,6 +297,7 @@ void ac_test_reset_pt_pool(ac_test_t *at)
 void ac_test_setup_pte(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);
@@ -328,6 +333,8 @@ void ac_test_setup_pte(ac_test_t *at)
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:
@@ -344,6 +351,8 @@ void ac_test_setup_pte(ac_test_t *at)
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;
}
@@ -357,10 +366,15 @@ void ac_test_setup_pte(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];
+pte_valid = pde_valid
+ at-flags[AC_PTE_PRESENT]
+ !at-flags[AC_PTE_BIT51];
 if (at-flags[AC_ACCESS_TWICE]) {
-   if (at-flags[AC_PDE_PRESENT]) {
+   if (pde_valid) {
at-expected_pde |= PT_ACCESSED_MASK;
-   if (at-flags[AC_PTE_PRESENT])
+   if (pte_valid)
at-expected_pte |= PT_ACCESSED_MASK;
}
 }
@@ -377,6 +391,9 @@ void ac_test_setup_pte(ac_test_t *at)
 if (!at-flags[AC_PDE_PRESENT]) {
at-expected_fault = 1;
at-expected_error = ~PFERR_PRESENT_MASK;
+} else if (!pde_valid) {
+at-expected_fault = 1;
+at-expected_error |= PFERR_RESERVED_MASK;
 }
 
 if (at-flags[AC_ACCESS_USER]  !at-flags[AC_PDE_USER])
@@ -404,6 +421,9 @@ void ac_test_setup_pte(ac_test_t *at)
 if (!at-flags[AC_PTE_PRESENT]) {
at-expected_fault = 1;
at-expected_error = ~PFERR_PRESENT_MASK;
+} else if (!pte_valid) {
+at-expected_fault = 1;
+at-expected_error |= PFERR_RESERVED_MASK;
 }
 
 if (at-flags[AC_ACCESS_USER]  !at-flags[AC_PTE_USER])
--
To unsubscribe from this list: send the line unsubscribe kvm-commits in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[PATCH] KVM: MMU: Use different shadows when EFER.NXE changes

2009-03-31 Thread Avi Kivity
From: Avi Kivity a...@redhat.com

A pte that is shadowed when the guest EFER.NXE=1 is not valid when
EFER.NXE=0; if bit 63 is set, the pte should cause a fault, and since the
shadow EFER always has NX enabled, this won't happen.

Fix by using a different shadow page table for different EFER.NXE bits.  This
allows vcpus to run correctly with different values of EFER.NXE, and for
transitions on this bit to be handled correctly without requiring a full
flush.

Signed-off-by: Avi Kivity a...@redhat.com

diff --git a/arch/x86/include/asm/kvm_host.h b/arch/x86/include/asm/kvm_host.h
index 548b97d..3fc4623 100644
--- a/arch/x86/include/asm/kvm_host.h
+++ b/arch/x86/include/asm/kvm_host.h
@@ -185,6 +185,7 @@ union kvm_mmu_page_role {
unsigned access:3;
unsigned invalid:1;
unsigned cr4_pge:1;
+   unsigned nxe:1;
};
 };
 
diff --git a/arch/x86/kvm/x86.c b/arch/x86/kvm/x86.c
index 9702353..bb30169 100644
--- a/arch/x86/kvm/x86.c
+++ b/arch/x86/kvm/x86.c
@@ -519,6 +519,9 @@ static void set_efer(struct kvm_vcpu *vcpu, u64 efer)
efer |= vcpu-arch.shadow_efer  EFER_LMA;
 
vcpu-arch.shadow_efer = efer;
+
+   vcpu-arch.mmu.base_role.nxe = (efer  EFER_NX)  !tdp_enabled;
+   kvm_mmu_reset_context(vcpu);
 }
 
 void kvm_enable_efer_bits(u64 mask)
--
To unsubscribe from this list: send the line unsubscribe kvm-commits in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[PATCH] KVM: remove pointless conditional before kfree() in lapic initialization

2009-03-31 Thread Avi Kivity
From: Wei Yongjun yj...@cn.fujitsu.com

Remove pointless conditional before kfree().

Signed-off-by: Wei Yongjun yj...@cn.fujitsu.com
Signed-off-by: Avi Kivity a...@redhat.com

diff --git a/arch/x86/kvm/x86.c b/arch/x86/kvm/x86.c
index bb30169..aeb0193 100644
--- a/arch/x86/kvm/x86.c
+++ b/arch/x86/kvm/x86.c
@@ -1588,8 +1588,7 @@ long kvm_arch_vcpu_ioctl(struct file *filp,
r = -EINVAL;
}
 out:
-   if (lapic)
-   kfree(lapic);
+   kfree(lapic);
return r;
 }
 
--
To unsubscribe from this list: send the line unsubscribe kvm-commits in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html