Message ID | 20221122161152.293072-27-mlevitsk@redhat.com (mailing list archive) |
---|---|
State | New, archived |
Headers | show |
Series | kvm-unit-tests: set of fixes and new tests | expand |
Am 22/11/2022 um 17:11 schrieb Maxim Levitsky: > Make test context have pointer to the guest function. > For V1 tests it is initialized from the test template, > for V2 tests, the test functions sets it. > > Signed-off-by: Maxim Levitsky <mlevitsk@redhat.com> Reviewed-by: Emanuele Giuseppe Esposito <eesposit@redhat.com> > --- > x86/svm.c | 12 ++++-------- > x86/svm.h | 4 ++-- > x86/svm_npt.c | 2 +- > x86/svm_tests.c | 26 +++++++++++++------------- > 4 files changed, 20 insertions(+), 24 deletions(-) > > diff --git a/x86/svm.c b/x86/svm.c > index a3279545..244555d4 100644 > --- a/x86/svm.c > +++ b/x86/svm.c > @@ -60,16 +60,11 @@ void inc_test_stage(struct svm_test_context *ctx) > barrier(); > } > > -static test_guest_func guest_main; > - > -void test_set_guest(test_guest_func func) > -{ > - guest_main = func; > -} > > static void test_thunk(struct svm_test_context *ctx) > { > - guest_main(ctx); > + if (ctx->guest_func) > + ctx->guest_func(ctx); > vmmcall(); > } > > @@ -93,6 +88,7 @@ static noinline void test_run(struct svm_test_context *ctx) > svm_vcpu_ident(ctx->vcpu); > > if (ctx->test->v2) { > + ctx->guest_func = NULL; > ctx->test->v2(ctx); > return; > } > @@ -100,7 +96,7 @@ static noinline void test_run(struct svm_test_context *ctx) > cli(); > > ctx->test->prepare(ctx); > - guest_main = ctx->test->guest_func; > + ctx->guest_func = ctx->test->guest_func; > ctx->vcpu->vmcb->save.rip = (ulong)test_thunk; > ctx->vcpu->regs.rsp = (ulong)(ctx->vcpu->stack); > ctx->vcpu->regs.rdi = (ulong)ctx; > diff --git a/x86/svm.h b/x86/svm.h > index ec181715..149b76c4 100644 > --- a/x86/svm.h > +++ b/x86/svm.h > @@ -15,6 +15,8 @@ struct svm_test_context { > > /* TODO: test cases currently are single threaded */ > struct svm_vcpu *vcpu; > + > + void (*guest_func)(struct svm_test_context *ctx); > }; > > struct svm_test { > @@ -44,7 +46,5 @@ void set_test_stage(struct svm_test_context *ctx, int s); > void inc_test_stage(struct svm_test_context *ctx); > int __svm_vmrun(struct svm_test_context *ctx, u64 rip); > int svm_vmrun(struct svm_test_context *ctx); > -void test_set_guest(test_guest_func func); > - > > #endif > diff --git a/x86/svm_npt.c b/x86/svm_npt.c > index 39fd7198..1e27f9ef 100644 > --- a/x86/svm_npt.c > +++ b/x86/svm_npt.c > @@ -332,7 +332,7 @@ static void svm_npt_rsvd_bits_test(struct svm_test_context *ctx) > sg_efer = guest_efer = vmcb->save.efer; > sg_cr4 = guest_cr4 = vmcb->save.cr4; > > - test_set_guest(basic_guest_main); > + ctx->guest_func = basic_guest_main; > > /* > * 4k PTEs don't have reserved bits if MAXPHYADDR >= 52, just skip the > diff --git a/x86/svm_tests.c b/x86/svm_tests.c > index bd92fcee..6d6dfa0e 100644 > --- a/x86/svm_tests.c > +++ b/x86/svm_tests.c > @@ -793,7 +793,7 @@ static void svm_tsc_scale_run_testcase(struct svm_test_context *ctx, > > guest_tsc_delay_value = (duration << TSC_SHIFT) * tsc_scale; > > - test_set_guest(svm_tsc_scale_guest); > + ctx->guest_func = svm_tsc_scale_guest; > vmcb->control.tsc_offset = tsc_offset; > wrmsr(MSR_AMD64_TSC_RATIO, (u64)(tsc_scale * (1ULL << 32))); > > @@ -2067,7 +2067,7 @@ static void svm_cr4_osxsave_test(struct svm_test_context *ctx) > > report(this_cpu_has(X86_FEATURE_OSXSAVE), "CPUID.01H:ECX.XSAVE set before VMRUN"); > > - test_set_guest(svm_cr4_osxsave_test_guest); > + ctx->guest_func = svm_cr4_osxsave_test_guest; > report(svm_vmrun(ctx) == SVM_EXIT_VMMCALL, > "svm_cr4_osxsave_test_guest finished with VMMCALL"); > > @@ -2494,7 +2494,7 @@ static void guest_rflags_test_db_handler(struct ex_regs *r) > > static void svm_guest_state_test(struct svm_test_context *ctx) > { > - test_set_guest(basic_guest_main); > + ctx->guest_func = basic_guest_main; > test_efer(ctx); > test_cr0(ctx); > test_cr3(ctx); > @@ -2633,7 +2633,7 @@ static void svm_vmload_vmsave(struct svm_test_context *ctx) > struct vmcb *vmcb = ctx->vcpu->vmcb; > u32 intercept_saved = vmcb->control.intercept; > > - test_set_guest(vmload_vmsave_guest_main); > + ctx->guest_func = vmload_vmsave_guest_main; > > /* > * Disabling intercept for VMLOAD and VMSAVE doesn't cause > @@ -2777,7 +2777,7 @@ static void pause_filter_run_test(struct svm_test_context *ctx, > { > struct vmcb *vmcb = ctx->vcpu->vmcb; > > - test_set_guest(pause_filter_test_guest_main); > + ctx->guest_func = pause_filter_test_guest_main; > > pause_test_counter = pause_iterations; > wait_counter = wait_iterations; > @@ -2832,7 +2832,7 @@ static void svm_no_nm_test(struct svm_test_context *ctx) > struct vmcb *vmcb = ctx->vcpu->vmcb; > > write_cr0(read_cr0() & ~X86_CR0_TS); > - test_set_guest((test_guest_func)fnop); > + ctx->guest_func = (test_guest_func)fnop; > > vmcb->save.cr0 = vmcb->save.cr0 & ~(X86_CR0_TS | X86_CR0_EM); > report(svm_vmrun(ctx) == SVM_EXIT_VMMCALL, > @@ -3149,7 +3149,7 @@ static void svm_intr_intercept_mix_if(struct svm_test_context *ctx) > vmcb->control.int_ctl &= ~V_INTR_MASKING_MASK; > vmcb->save.rflags &= ~X86_EFLAGS_IF; > > - test_set_guest(svm_intr_intercept_mix_if_guest); > + ctx->guest_func = svm_intr_intercept_mix_if_guest; > cli(); > apic_icr_write(APIC_DEST_SELF | APIC_DEST_PHYSICAL | APIC_DM_FIXED | 0x55, 0); > svm_intr_intercept_mix_run_guest(ctx, &dummy_isr_recevied, SVM_EXIT_INTR); > @@ -3184,7 +3184,7 @@ static void svm_intr_intercept_mix_gif(struct svm_test_context *ctx) > vmcb->control.int_ctl &= ~V_INTR_MASKING_MASK; > vmcb->save.rflags &= ~X86_EFLAGS_IF; > > - test_set_guest(svm_intr_intercept_mix_gif_guest); > + ctx->guest_func = svm_intr_intercept_mix_gif_guest; > cli(); > apic_icr_write(APIC_DEST_SELF | APIC_DEST_PHYSICAL | APIC_DM_FIXED | 0x55, 0); > svm_intr_intercept_mix_run_guest(ctx, &dummy_isr_recevied, SVM_EXIT_INTR); > @@ -3216,7 +3216,7 @@ static void svm_intr_intercept_mix_gif2(struct svm_test_context *ctx) > vmcb->control.int_ctl &= ~V_INTR_MASKING_MASK; > vmcb->save.rflags |= X86_EFLAGS_IF; > > - test_set_guest(svm_intr_intercept_mix_gif_guest2); > + ctx->guest_func = svm_intr_intercept_mix_gif_guest2; > svm_intr_intercept_mix_run_guest(ctx, &dummy_isr_recevied, SVM_EXIT_INTR); > } > > @@ -3247,7 +3247,7 @@ static void svm_intr_intercept_mix_nmi(struct svm_test_context *ctx) > vmcb->control.int_ctl &= ~V_INTR_MASKING_MASK; > vmcb->save.rflags |= X86_EFLAGS_IF; > > - test_set_guest(svm_intr_intercept_mix_nmi_guest); > + ctx->guest_func = svm_intr_intercept_mix_nmi_guest; > svm_intr_intercept_mix_run_guest(ctx, &nmi_recevied, SVM_EXIT_NMI); > } > > @@ -3271,7 +3271,7 @@ static void svm_intr_intercept_mix_smi(struct svm_test_context *ctx) > > vmcb->control.intercept |= (1 << INTERCEPT_SMI); > vmcb->control.int_ctl &= ~V_INTR_MASKING_MASK; > - test_set_guest(svm_intr_intercept_mix_smi_guest); > + ctx->guest_func = svm_intr_intercept_mix_smi_guest; > svm_intr_intercept_mix_run_guest(ctx, NULL, SVM_EXIT_SMI); > } > > @@ -3346,7 +3346,7 @@ static void svm_exception_test(struct svm_test_context *ctx) > > for (i = 0; i < ARRAY_SIZE(svm_exception_tests); i++) { > t = &svm_exception_tests[i]; > - test_set_guest((test_guest_func)t->guest_code); > + ctx->guest_func = (test_guest_func)t->guest_code; > > handle_exception_in_l2(ctx, t->vector); > svm_vcpu_ident(ctx->vcpu); > @@ -3366,7 +3366,7 @@ static void svm_shutdown_intercept_test(struct svm_test_context *ctx) > { > struct vmcb *vmcb = ctx->vcpu->vmcb; > > - test_set_guest(shutdown_intercept_test_guest); > + ctx->guest_func = shutdown_intercept_test_guest; > vmcb->save.idtr.base = (u64)alloc_vpage(); > vmcb->control.intercept |= (1ULL << INTERCEPT_SHUTDOWN); > svm_vmrun(ctx); >
diff --git a/x86/svm.c b/x86/svm.c index a3279545..244555d4 100644 --- a/x86/svm.c +++ b/x86/svm.c @@ -60,16 +60,11 @@ void inc_test_stage(struct svm_test_context *ctx) barrier(); } -static test_guest_func guest_main; - -void test_set_guest(test_guest_func func) -{ - guest_main = func; -} static void test_thunk(struct svm_test_context *ctx) { - guest_main(ctx); + if (ctx->guest_func) + ctx->guest_func(ctx); vmmcall(); } @@ -93,6 +88,7 @@ static noinline void test_run(struct svm_test_context *ctx) svm_vcpu_ident(ctx->vcpu); if (ctx->test->v2) { + ctx->guest_func = NULL; ctx->test->v2(ctx); return; } @@ -100,7 +96,7 @@ static noinline void test_run(struct svm_test_context *ctx) cli(); ctx->test->prepare(ctx); - guest_main = ctx->test->guest_func; + ctx->guest_func = ctx->test->guest_func; ctx->vcpu->vmcb->save.rip = (ulong)test_thunk; ctx->vcpu->regs.rsp = (ulong)(ctx->vcpu->stack); ctx->vcpu->regs.rdi = (ulong)ctx; diff --git a/x86/svm.h b/x86/svm.h index ec181715..149b76c4 100644 --- a/x86/svm.h +++ b/x86/svm.h @@ -15,6 +15,8 @@ struct svm_test_context { /* TODO: test cases currently are single threaded */ struct svm_vcpu *vcpu; + + void (*guest_func)(struct svm_test_context *ctx); }; struct svm_test { @@ -44,7 +46,5 @@ void set_test_stage(struct svm_test_context *ctx, int s); void inc_test_stage(struct svm_test_context *ctx); int __svm_vmrun(struct svm_test_context *ctx, u64 rip); int svm_vmrun(struct svm_test_context *ctx); -void test_set_guest(test_guest_func func); - #endif diff --git a/x86/svm_npt.c b/x86/svm_npt.c index 39fd7198..1e27f9ef 100644 --- a/x86/svm_npt.c +++ b/x86/svm_npt.c @@ -332,7 +332,7 @@ static void svm_npt_rsvd_bits_test(struct svm_test_context *ctx) sg_efer = guest_efer = vmcb->save.efer; sg_cr4 = guest_cr4 = vmcb->save.cr4; - test_set_guest(basic_guest_main); + ctx->guest_func = basic_guest_main; /* * 4k PTEs don't have reserved bits if MAXPHYADDR >= 52, just skip the diff --git a/x86/svm_tests.c b/x86/svm_tests.c index bd92fcee..6d6dfa0e 100644 --- a/x86/svm_tests.c +++ b/x86/svm_tests.c @@ -793,7 +793,7 @@ static void svm_tsc_scale_run_testcase(struct svm_test_context *ctx, guest_tsc_delay_value = (duration << TSC_SHIFT) * tsc_scale; - test_set_guest(svm_tsc_scale_guest); + ctx->guest_func = svm_tsc_scale_guest; vmcb->control.tsc_offset = tsc_offset; wrmsr(MSR_AMD64_TSC_RATIO, (u64)(tsc_scale * (1ULL << 32))); @@ -2067,7 +2067,7 @@ static void svm_cr4_osxsave_test(struct svm_test_context *ctx) report(this_cpu_has(X86_FEATURE_OSXSAVE), "CPUID.01H:ECX.XSAVE set before VMRUN"); - test_set_guest(svm_cr4_osxsave_test_guest); + ctx->guest_func = svm_cr4_osxsave_test_guest; report(svm_vmrun(ctx) == SVM_EXIT_VMMCALL, "svm_cr4_osxsave_test_guest finished with VMMCALL"); @@ -2494,7 +2494,7 @@ static void guest_rflags_test_db_handler(struct ex_regs *r) static void svm_guest_state_test(struct svm_test_context *ctx) { - test_set_guest(basic_guest_main); + ctx->guest_func = basic_guest_main; test_efer(ctx); test_cr0(ctx); test_cr3(ctx); @@ -2633,7 +2633,7 @@ static void svm_vmload_vmsave(struct svm_test_context *ctx) struct vmcb *vmcb = ctx->vcpu->vmcb; u32 intercept_saved = vmcb->control.intercept; - test_set_guest(vmload_vmsave_guest_main); + ctx->guest_func = vmload_vmsave_guest_main; /* * Disabling intercept for VMLOAD and VMSAVE doesn't cause @@ -2777,7 +2777,7 @@ static void pause_filter_run_test(struct svm_test_context *ctx, { struct vmcb *vmcb = ctx->vcpu->vmcb; - test_set_guest(pause_filter_test_guest_main); + ctx->guest_func = pause_filter_test_guest_main; pause_test_counter = pause_iterations; wait_counter = wait_iterations; @@ -2832,7 +2832,7 @@ static void svm_no_nm_test(struct svm_test_context *ctx) struct vmcb *vmcb = ctx->vcpu->vmcb; write_cr0(read_cr0() & ~X86_CR0_TS); - test_set_guest((test_guest_func)fnop); + ctx->guest_func = (test_guest_func)fnop; vmcb->save.cr0 = vmcb->save.cr0 & ~(X86_CR0_TS | X86_CR0_EM); report(svm_vmrun(ctx) == SVM_EXIT_VMMCALL, @@ -3149,7 +3149,7 @@ static void svm_intr_intercept_mix_if(struct svm_test_context *ctx) vmcb->control.int_ctl &= ~V_INTR_MASKING_MASK; vmcb->save.rflags &= ~X86_EFLAGS_IF; - test_set_guest(svm_intr_intercept_mix_if_guest); + ctx->guest_func = svm_intr_intercept_mix_if_guest; cli(); apic_icr_write(APIC_DEST_SELF | APIC_DEST_PHYSICAL | APIC_DM_FIXED | 0x55, 0); svm_intr_intercept_mix_run_guest(ctx, &dummy_isr_recevied, SVM_EXIT_INTR); @@ -3184,7 +3184,7 @@ static void svm_intr_intercept_mix_gif(struct svm_test_context *ctx) vmcb->control.int_ctl &= ~V_INTR_MASKING_MASK; vmcb->save.rflags &= ~X86_EFLAGS_IF; - test_set_guest(svm_intr_intercept_mix_gif_guest); + ctx->guest_func = svm_intr_intercept_mix_gif_guest; cli(); apic_icr_write(APIC_DEST_SELF | APIC_DEST_PHYSICAL | APIC_DM_FIXED | 0x55, 0); svm_intr_intercept_mix_run_guest(ctx, &dummy_isr_recevied, SVM_EXIT_INTR); @@ -3216,7 +3216,7 @@ static void svm_intr_intercept_mix_gif2(struct svm_test_context *ctx) vmcb->control.int_ctl &= ~V_INTR_MASKING_MASK; vmcb->save.rflags |= X86_EFLAGS_IF; - test_set_guest(svm_intr_intercept_mix_gif_guest2); + ctx->guest_func = svm_intr_intercept_mix_gif_guest2; svm_intr_intercept_mix_run_guest(ctx, &dummy_isr_recevied, SVM_EXIT_INTR); } @@ -3247,7 +3247,7 @@ static void svm_intr_intercept_mix_nmi(struct svm_test_context *ctx) vmcb->control.int_ctl &= ~V_INTR_MASKING_MASK; vmcb->save.rflags |= X86_EFLAGS_IF; - test_set_guest(svm_intr_intercept_mix_nmi_guest); + ctx->guest_func = svm_intr_intercept_mix_nmi_guest; svm_intr_intercept_mix_run_guest(ctx, &nmi_recevied, SVM_EXIT_NMI); } @@ -3271,7 +3271,7 @@ static void svm_intr_intercept_mix_smi(struct svm_test_context *ctx) vmcb->control.intercept |= (1 << INTERCEPT_SMI); vmcb->control.int_ctl &= ~V_INTR_MASKING_MASK; - test_set_guest(svm_intr_intercept_mix_smi_guest); + ctx->guest_func = svm_intr_intercept_mix_smi_guest; svm_intr_intercept_mix_run_guest(ctx, NULL, SVM_EXIT_SMI); } @@ -3346,7 +3346,7 @@ static void svm_exception_test(struct svm_test_context *ctx) for (i = 0; i < ARRAY_SIZE(svm_exception_tests); i++) { t = &svm_exception_tests[i]; - test_set_guest((test_guest_func)t->guest_code); + ctx->guest_func = (test_guest_func)t->guest_code; handle_exception_in_l2(ctx, t->vector); svm_vcpu_ident(ctx->vcpu); @@ -3366,7 +3366,7 @@ static void svm_shutdown_intercept_test(struct svm_test_context *ctx) { struct vmcb *vmcb = ctx->vcpu->vmcb; - test_set_guest(shutdown_intercept_test_guest); + ctx->guest_func = shutdown_intercept_test_guest; vmcb->save.idtr.base = (u64)alloc_vpage(); vmcb->control.intercept |= (1ULL << INTERCEPT_SHUTDOWN); svm_vmrun(ctx);
Make test context have pointer to the guest function. For V1 tests it is initialized from the test template, for V2 tests, the test functions sets it. Signed-off-by: Maxim Levitsky <mlevitsk@redhat.com> --- x86/svm.c | 12 ++++-------- x86/svm.h | 4 ++-- x86/svm_npt.c | 2 +- x86/svm_tests.c | 26 +++++++++++++------------- 4 files changed, 20 insertions(+), 24 deletions(-)