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@xxxxxxxxxx> --- 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); -- 2.34.3