Add the SPEC_CTRL tests for SVM and make sure the settings on L2 guests does not overwrite the L1 guest's SPEC_CTRL settings. Test Method. 1. Save the L1 guests SPEC_CTRL settings(rdmsr). Normally 0. 2. Start the L2 guest 3. Change the L2 guests SPEC_CTRL settings. 4. Exit the L2 guest. 5. Verify if the settings from step #1 still holds. Signed-off-by: Babu Moger <babu.moger@xxxxxxx> --- x86/svm_tests.c | 52 ++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 52 insertions(+) diff --git a/x86/svm_tests.c b/x86/svm_tests.c index 29a0b59..2867337 100644 --- a/x86/svm_tests.c +++ b/x86/svm_tests.c @@ -2002,6 +2002,55 @@ static bool init_intercept_check(struct svm_test *test) return init_intercept; } +/* Indirect Branch Restricted Speculation(bit 0) */ +#define SPEC_CTRL_IBRS 1 +/* Single Thread Indirect Branch Predictor (STIBP)(bit 1) */ +#define SPEC_CTRL_STIBP 2 +/* Speculative Store Bypass Disable (bit 2) */ +#define SPEC_CTRL_SSBD 4 + +static bool spec_ctrl_supported(void) +{ + return this_cpu_has(X86_FEATURE_AMD_SSBD) || + this_cpu_has(X86_FEATURE_AMD_STIBP) || + this_cpu_has(X86_FEATURE_AMD_IBRS); +} + +static void spec_ctrl_prepare(struct svm_test *test) +{ + vmcb_ident(vmcb); + test->scratch = rdmsr(MSR_IA32_SPEC_CTRL); +} + +/* + * Write it twice to bypass the interception. The first write to + * SPEC_CTRL is intercepted in older kernels. + */ +static void spec_ctrl_test(struct svm_test *test) +{ + int spec_ctrl = 0; + + if (this_cpu_has(X86_FEATURE_AMD_SSBD)) + spec_ctrl |= SPEC_CTRL_SSBD; + if (this_cpu_has(X86_FEATURE_AMD_STIBP)) + spec_ctrl |= SPEC_CTRL_STIBP; + if (this_cpu_has(X86_FEATURE_AMD_IBRS)) + spec_ctrl |= SPEC_CTRL_IBRS; + + wrmsr(MSR_IA32_SPEC_CTRL, spec_ctrl); + wrmsr(MSR_IA32_SPEC_CTRL, spec_ctrl); +} + +static bool spec_ctrl_finished(struct svm_test *test) +{ + return vmcb->control.exit_code == SVM_EXIT_VMMCALL; +} + +static bool spec_ctrl_check(struct svm_test *test) +{ + return test->scratch == rdmsr(MSR_IA32_SPEC_CTRL); +} + #define TEST(name) { #name, .v2 = name } /* @@ -2492,6 +2541,9 @@ struct svm_test svm_tests[] = { { "svm_init_intercept_test", smp_supported, init_intercept_prepare, default_prepare_gif_clear, init_intercept_test, init_intercept_finished, init_intercept_check, .on_vcpu = 2 }, + { "SPEC_CTRL", spec_ctrl_supported, spec_ctrl_prepare, + default_prepare_gif_clear, spec_ctrl_test, + spec_ctrl_finished, spec_ctrl_check }, TEST(svm_cr4_osxsave_test), TEST(svm_guest_state_test), TEST(svm_vmrun_errata_test),