* [PATCH kvm-unit-tests 0/2] svm: INIT test and test_run on selected vcpu @ 2020-06-08 12:27 Cathy Avery 2020-06-08 12:27 ` [PATCH kvm-unit-tests 1/2] svm: Add ability to execute test via test_run on a vcpu other than vcpu 0 Cathy Avery 2020-06-08 12:28 ` [PATCH kvm-unit-tests 2/2] svm: INIT intercept test Cathy Avery 0 siblings, 2 replies; 5+ messages in thread From: Cathy Avery @ 2020-06-08 12:27 UTC (permalink / raw) To: linux-kernel, kvm, pbonzini INIT intercept test and the ability to execute test_run on a selected vcpu. Cathy Avery (2): svm: Add ability to execute test via test_run on a vcpu other than vcpu 0 svm: INIT intercept test x86/svm.c | 49 ++++++++++++++++++++++++++++++++++++++++++++++++- x86/svm.h | 13 +++++++++++++ x86/svm_tests.c | 40 ++++++++++++++++++++++++++++++++++++++++ 3 files changed, 101 insertions(+), 1 deletion(-) -- 2.20.1 ^ permalink raw reply [flat|nested] 5+ messages in thread
* [PATCH kvm-unit-tests 1/2] svm: Add ability to execute test via test_run on a vcpu other than vcpu 0 2020-06-08 12:27 [PATCH kvm-unit-tests 0/2] svm: INIT test and test_run on selected vcpu Cathy Avery @ 2020-06-08 12:27 ` Cathy Avery 2020-06-08 12:40 ` Paolo Bonzini 2020-06-08 12:28 ` [PATCH kvm-unit-tests 2/2] svm: INIT intercept test Cathy Avery 1 sibling, 1 reply; 5+ messages in thread From: Cathy Avery @ 2020-06-08 12:27 UTC (permalink / raw) To: linux-kernel, kvm, pbonzini When running tests that can result in a vcpu being left in an indeterminate state it is useful to be able to run the test on a vcpu other than 0. This patch allows test_run to be executed on any vcpu indicated by the on_vcpu member of the svm_test struct. The initialized state of the vcpu0 registers used to populate the vmcb is carried forward to the other vcpus. Signed-off-by: Cathy Avery <cavery@redhat.com> --- x86/svm.c | 49 ++++++++++++++++++++++++++++++++++++++++++++++++- x86/svm.h | 13 +++++++++++++ 2 files changed, 61 insertions(+), 1 deletion(-) diff --git a/x86/svm.c b/x86/svm.c index 41685bf..9f7ae7e 100644 --- a/x86/svm.c +++ b/x86/svm.c @@ -367,6 +367,45 @@ test_wanted(const char *name, char *filters[], int filter_count) } } +static void set_additional_vpcu_regs(struct extra_vcpu_info *info) +{ + wrmsr(MSR_VM_HSAVE_PA, info->hsave); + wrmsr(MSR_EFER, rdmsr(MSR_EFER) | EFER_SVME); + wrmsr(MSR_EFER, rdmsr(MSR_EFER) | EFER_NX); + write_cr3(info->cr3); + write_cr4(info->cr4); + write_cr0(info->cr0); + write_dr6(info->dr6); + write_dr7(info->dr7); + write_cr2(info->cr2); + wrmsr(MSR_IA32_CR_PAT, info->g_pat); + wrmsr(MSR_IA32_DEBUGCTLMSR, info->dbgctl); +} + +static void get_additional_vcpu_regs(struct extra_vcpu_info *info) +{ + info->hsave = rdmsr(MSR_VM_HSAVE_PA); + info->cr3 = read_cr3(); + info->cr4 = read_cr4(); + info->cr0 = read_cr0(); + info->dr7 = read_dr7(); + info->dr6 = read_dr6(); + info->cr2 = read_cr2(); + info->g_pat = rdmsr(MSR_IA32_CR_PAT); + info->dbgctl = rdmsr(MSR_IA32_DEBUGCTLMSR); +} + +static void init_additional_vcpu_regs(void) +{ + int i; + struct extra_vcpu_info info; + + get_additional_vcpu_regs(&info); + + for (i = 1; i < cpu_count(); i++) + on_cpu(i, (void *)set_additional_vpcu_regs, &info); +} + int main(int ac, char **av) { int i = 0; @@ -384,6 +423,8 @@ int main(int ac, char **av) setup_svm(); + init_additional_vcpu_regs(); + vmcb = alloc_page(); for (; svm_tests[i].name != NULL; i++) { @@ -392,7 +433,13 @@ int main(int ac, char **av) if (svm_tests[i].supported && !svm_tests[i].supported()) continue; if (svm_tests[i].v2 == NULL) { - test_run(&svm_tests[i]); + if (svm_tests[i].on_vcpu) { + if (cpu_count() <= svm_tests[i].on_vcpu) + continue; + on_cpu(svm_tests[i].on_vcpu, (void *)test_run, &svm_tests[i]); + } + else + test_run(&svm_tests[i]); } else { vmcb_ident(vmcb); v2_test = &(svm_tests[i]); diff --git a/x86/svm.h b/x86/svm.h index 645deb7..d023a32 100644 --- a/x86/svm.h +++ b/x86/svm.h @@ -338,6 +338,7 @@ struct svm_test { ulong scratch; /* Alternative test interface. */ void (*v2)(void); + int on_vcpu; }; struct regs { @@ -360,6 +361,18 @@ struct regs { u64 rflags; }; +struct extra_vcpu_info { + u64 hsave; + u64 cr3; + u64 cr4; + u64 cr0; + u64 dr7; + u64 dr6; + u64 cr2; + u64 g_pat; + u64 dbgctl; +}; + typedef void (*test_guest_func)(struct svm_test *); u64 *npt_get_pte(u64 address); -- 2.20.1 ^ permalink raw reply related [flat|nested] 5+ messages in thread
* Re: [PATCH kvm-unit-tests 1/2] svm: Add ability to execute test via test_run on a vcpu other than vcpu 0 2020-06-08 12:27 ` [PATCH kvm-unit-tests 1/2] svm: Add ability to execute test via test_run on a vcpu other than vcpu 0 Cathy Avery @ 2020-06-08 12:40 ` Paolo Bonzini 0 siblings, 0 replies; 5+ messages in thread From: Paolo Bonzini @ 2020-06-08 12:40 UTC (permalink / raw) To: Cathy Avery, linux-kernel, kvm On 08/06/20 14:27, Cathy Avery wrote: > When running tests that can result in a vcpu being left in an > indeterminate state it is useful to be able to run the test on > a vcpu other than 0. This patch allows test_run to be executed > on any vcpu indicated by the on_vcpu member of the svm_test struct. > The initialized state of the vcpu0 registers used to populate the > vmcb is carried forward to the other vcpus. > > Signed-off-by: Cathy Avery <cavery@redhat.com> > --- > x86/svm.c | 49 ++++++++++++++++++++++++++++++++++++++++++++++++- > x86/svm.h | 13 +++++++++++++ > 2 files changed, 61 insertions(+), 1 deletion(-) > > diff --git a/x86/svm.c b/x86/svm.c > index 41685bf..9f7ae7e 100644 > --- a/x86/svm.c > +++ b/x86/svm.c > @@ -367,6 +367,45 @@ test_wanted(const char *name, char *filters[], int filter_count) > } > } > > +static void set_additional_vpcu_regs(struct extra_vcpu_info *info) > +{ > + wrmsr(MSR_VM_HSAVE_PA, info->hsave); > + wrmsr(MSR_EFER, rdmsr(MSR_EFER) | EFER_SVME); > + wrmsr(MSR_EFER, rdmsr(MSR_EFER) | EFER_NX); > + write_cr3(info->cr3); > + write_cr4(info->cr4); > + write_cr0(info->cr0); > + write_dr6(info->dr6); > + write_dr7(info->dr7); > + write_cr2(info->cr2); > + wrmsr(MSR_IA32_CR_PAT, info->g_pat); > + wrmsr(MSR_IA32_DEBUGCTLMSR, info->dbgctl); > +} > + > +static void get_additional_vcpu_regs(struct extra_vcpu_info *info) > +{ > + info->hsave = rdmsr(MSR_VM_HSAVE_PA); > + info->cr3 = read_cr3(); > + info->cr4 = read_cr4(); > + info->cr0 = read_cr0(); > + info->dr7 = read_dr7(); > + info->dr6 = read_dr6(); > + info->cr2 = read_cr2(); > + info->g_pat = rdmsr(MSR_IA32_CR_PAT); > + info->dbgctl = rdmsr(MSR_IA32_DEBUGCTLMSR); > +} Some tweaks are needed here: - DR6/DR7/CR2/DEBUGCTL should not be needed, are they? Same for PAT since it's not modified by the tests and defaults to the "right" value (0x0007040600070406ULL) rather than zero. - HSAVE should be set to a different page for each vCPU - The on_cpu to set EFER should be in setup_svm, rather than a separate function - The on_cpu to set cr0/cr3/cr4 should be in setup_vm. Paolo ^ permalink raw reply [flat|nested] 5+ messages in thread
* [PATCH kvm-unit-tests 2/2] svm: INIT intercept test 2020-06-08 12:27 [PATCH kvm-unit-tests 0/2] svm: INIT test and test_run on selected vcpu Cathy Avery 2020-06-08 12:27 ` [PATCH kvm-unit-tests 1/2] svm: Add ability to execute test via test_run on a vcpu other than vcpu 0 Cathy Avery @ 2020-06-08 12:28 ` Cathy Avery 2020-06-08 12:47 ` Paolo Bonzini 1 sibling, 1 reply; 5+ messages in thread From: Cathy Avery @ 2020-06-08 12:28 UTC (permalink / raw) To: linux-kernel, kvm, pbonzini INIT vcpu 2 and intercept the INIT. This test will leave the vcpu in an unusable state. Signed-off-by: Cathy Avery <cavery@redhat.com> --- x86/svm_tests.c | 40 ++++++++++++++++++++++++++++++++++++++++ 1 file changed, 40 insertions(+) diff --git a/x86/svm_tests.c b/x86/svm_tests.c index c1abd55..a4dbe91 100644 --- a/x86/svm_tests.c +++ b/x86/svm_tests.c @@ -1789,6 +1789,43 @@ static bool virq_inject_check(struct svm_test *test) return get_test_stage(test) == 5; } +static volatile bool init_intercept; + +static void init_signal_intercept_prepare(struct svm_test *test) +{ + + vmcb_ident(vmcb); + vmcb->control.intercept |= (1ULL << INTERCEPT_INIT); + init_intercept = false; +} + +static void init_signal_test(struct svm_test *test) +{ + apic_icr_write(APIC_DEST_SELF | APIC_DEST_PHYSICAL | APIC_DM_INIT | APIC_INT_ASSERT, 0); +} + +static bool init_signal_finished(struct svm_test *test) +{ + vmcb->save.rip += 3; + + if (vmcb->control.exit_code != SVM_EXIT_INIT) { + report(false, "VMEXIT not due to init intercept. Exit reason 0x%x", + vmcb->control.exit_code); + return true; + } + + init_intercept = true; + + report(true, "INIT to vcpu intercepted"); + + return true; +} + +static bool init_signal_check(struct svm_test *test) +{ + return init_intercept; +} + #define TEST(name) { #name, .v2 = name } /* @@ -1950,6 +1987,9 @@ struct svm_test svm_tests[] = { { "virq_inject", default_supported, virq_inject_prepare, default_prepare_gif_clear, virq_inject_test, virq_inject_finished, virq_inject_check }, + { "svm_init_signal_intercept_test", default_supported, init_signal_intercept_prepare, + default_prepare_gif_clear, init_signal_test, + init_signal_finished, init_signal_check, .on_vcpu = 2 }, TEST(svm_guest_state_test), { NULL, NULL, NULL, NULL, NULL, NULL, NULL } }; -- 2.20.1 ^ permalink raw reply related [flat|nested] 5+ messages in thread
* Re: [PATCH kvm-unit-tests 2/2] svm: INIT intercept test 2020-06-08 12:28 ` [PATCH kvm-unit-tests 2/2] svm: INIT intercept test Cathy Avery @ 2020-06-08 12:47 ` Paolo Bonzini 0 siblings, 0 replies; 5+ messages in thread From: Paolo Bonzini @ 2020-06-08 12:47 UTC (permalink / raw) To: Cathy Avery, linux-kernel, kvm On 08/06/20 14:28, Cathy Avery wrote: > INIT vcpu 2 and intercept the INIT. This test > will leave the vcpu in an unusable state. > > Signed-off-by: Cathy Avery <cavery@redhat.com> It should be possible to reinitialize the vCPU using a SIPI interrupt, like old = cpu_online_count--; apic_icr_write(APIC_DEST_PHYSICAL | APIC_DEST_SIPI, id_map[cpu]); while (cpu_online_count != old) cpu_relax(); You can test this by using vCPU 1 to run this test. Paolo > --- > x86/svm_tests.c | 40 ++++++++++++++++++++++++++++++++++++++++ > 1 file changed, 40 insertions(+) > > diff --git a/x86/svm_tests.c b/x86/svm_tests.c > index c1abd55..a4dbe91 100644 > --- a/x86/svm_tests.c > +++ b/x86/svm_tests.c > @@ -1789,6 +1789,43 @@ static bool virq_inject_check(struct svm_test *test) > return get_test_stage(test) == 5; > } > > +static volatile bool init_intercept; > + > +static void init_signal_intercept_prepare(struct svm_test *test) > +{ > + > + vmcb_ident(vmcb); > + vmcb->control.intercept |= (1ULL << INTERCEPT_INIT); > + init_intercept = false; > +} > + > +static void init_signal_test(struct svm_test *test) > +{ > + apic_icr_write(APIC_DEST_SELF | APIC_DEST_PHYSICAL | APIC_DM_INIT | APIC_INT_ASSERT, 0); > +} > + > +static bool init_signal_finished(struct svm_test *test) > +{ > + vmcb->save.rip += 3; > + > + if (vmcb->control.exit_code != SVM_EXIT_INIT) { > + report(false, "VMEXIT not due to init intercept. Exit reason 0x%x", > + vmcb->control.exit_code); > + return true; > + } > + > + init_intercept = true; > + > + report(true, "INIT to vcpu intercepted"); > + > + return true; > +} > + > +static bool init_signal_check(struct svm_test *test) > +{ > + return init_intercept; > +} > + > #define TEST(name) { #name, .v2 = name } > > /* > @@ -1950,6 +1987,9 @@ struct svm_test svm_tests[] = { > { "virq_inject", default_supported, virq_inject_prepare, > default_prepare_gif_clear, virq_inject_test, > virq_inject_finished, virq_inject_check }, > + { "svm_init_signal_intercept_test", default_supported, init_signal_intercept_prepare, > + default_prepare_gif_clear, init_signal_test, > + init_signal_finished, init_signal_check, .on_vcpu = 2 }, > TEST(svm_guest_state_test), > { NULL, NULL, NULL, NULL, NULL, NULL, NULL } > }; > ^ permalink raw reply [flat|nested] 5+ messages in thread
end of thread, other threads:[~2020-06-08 12:47 UTC | newest] Thread overview: 5+ messages (download: mbox.gz / follow: Atom feed) -- links below jump to the message on this page -- 2020-06-08 12:27 [PATCH kvm-unit-tests 0/2] svm: INIT test and test_run on selected vcpu Cathy Avery 2020-06-08 12:27 ` [PATCH kvm-unit-tests 1/2] svm: Add ability to execute test via test_run on a vcpu other than vcpu 0 Cathy Avery 2020-06-08 12:40 ` Paolo Bonzini 2020-06-08 12:28 ` [PATCH kvm-unit-tests 2/2] svm: INIT intercept test Cathy Avery 2020-06-08 12:47 ` Paolo Bonzini
This is a public inbox, see mirroring instructions for how to clone and mirror all data and code used for this inbox; as well as URLs for NNTP newsgroup(s).