[PATCH kvm-unit-tests] vmexit: add test toggling CR0.WP and CR4.PGE

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

 



CR0.WP changes the MMU permissions but does not cause a TLB flush;
CR4.PGE is the opposite (at least as far as KVM as concerned).

This makes both of them interesting from a performance perspective,
so add new vmexit tests.

Signed-off-by: Paolo Bonzini <pbonzini@xxxxxxxxxx>
---
 x86/access.c      |  3 +++
 x86/unittests.cfg | 12 ++++++++++++
 x86/vmexit.c      | 16 ++++++++++++++++
 3 files changed, 31 insertions(+)

diff --git a/x86/access.c b/x86/access.c
index 83c8221..21b4d74 100644
--- a/x86/access.c
+++ b/x86/access.c
@@ -251,6 +251,9 @@ static void set_cr0_wp(int wp)
 static void clear_user_mask(pt_element_t *ptep, int level, unsigned long virt)
 {
 	*ptep &= ~PT_USER_MASK;
+
+	/* Flush to avoid spurious #PF */
+	invlpg((void*)virt);
 }
 
 static void set_user_mask(pt_element_t *ptep, int level, unsigned long virt)
diff --git a/x86/unittests.cfg b/x86/unittests.cfg
index 62a6692..cef09d2 100644
--- a/x86/unittests.cfg
+++ b/x86/unittests.cfg
@@ -118,6 +118,18 @@ file = vmexit.flat
 groups = vmexit
 extra_params = -cpu qemu64,+x2apic,+tsc-deadline -append tscdeadline_immed
 
+[vmexit_cr0_wp]
+file = vmexit.flat
+smp = 2
+extra_params = -append 'toggle_cr0_wp'
+groups = vmexit
+
+[vmexit_cr4_pge]
+file = vmexit.flat
+smp = 2
+extra_params = -append 'toggle_cr4_pge'
+groups = vmexit
+
 [access]
 file = access_test.flat
 arch = x86_64
diff --git a/x86/vmexit.c b/x86/vmexit.c
index 8cfb36b..4adec78 100644
--- a/x86/vmexit.c
+++ b/x86/vmexit.c
@@ -20,6 +20,7 @@ struct test {
 #define GOAL (1ull << 30)
 
 static int nr_cpus;
+static u64 cr4_shadow;
 
 static void cpuid_test(void)
 {
@@ -459,6 +460,18 @@ static void wr_ibpb_msr(void)
 	wrmsr(MSR_IA32_PRED_CMD, 1);
 }
 
+static void toggle_cr0_wp(void)
+{
+	write_cr0(X86_CR0_PE|X86_CR0_PG);
+	write_cr0(X86_CR0_PE|X86_CR0_WP|X86_CR0_PG);
+}
+
+static void toggle_cr4_pge(void)
+{
+	write_cr4(cr4_shadow ^ X86_CR4_PGE);
+	write_cr4(cr4_shadow);
+}
+
 static struct test tests[] = {
 	{ cpuid_test, "cpuid", .parallel = 1,  },
 	{ vmcall, "vmcall", .parallel = 1, },
@@ -492,6 +505,8 @@ static struct test tests[] = {
 	{ wr_ibpb_msr, "wr_ibpb_msr", has_ibpb, .parallel = 1 },
 	{ wr_tsc_adjust_msr, "wr_tsc_adjust_msr", .parallel = 1 },
 	{ rd_tsc_adjust_msr, "rd_tsc_adjust_msr", .parallel = 1 },
+	{ toggle_cr0_wp, "toggle_cr0_wp" , .parallel = 1, },
+	{ toggle_cr4_pge, "toggle_cr4_pge" , .parallel = 1, },
 	{ NULL, "pci-mem", .parallel = 0, .next = pci_mem_next },
 	{ NULL, "pci-io", .parallel = 0, .next = pci_io_next },
 };
@@ -580,6 +595,7 @@ int main(int ac, char **av)
 	int ret;
 
 	setup_vm();
+	cr4_shadow = read_cr4();
 	handle_irq(IPI_TEST_VECTOR, self_ipi_isr);
 	nr_cpus = cpu_count();
 
-- 
2.31.1




[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