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