From: Swapnil Paratey <swapnil.paratey@xxxxxxx> Test for #GP when VMRUN is executed with unaligned VMCB and VMCB address bits set beyond physical address width. --- x86/svm.c | 42 ++++++++++++++++++++++++++++++++++++++++++ x86/unittests.cfg | 5 +++++ 2 files changed, 47 insertions(+) diff --git a/x86/svm.c b/x86/svm.c index b71178a..2eb97e2 100644 --- a/x86/svm.c +++ b/x86/svm.c @@ -1088,6 +1088,43 @@ static void test_svm_virtual_machine_control() test_for_exception(GP_VECTOR, &set_msr_efer, (void*)(&msr_value))); } +static void vmrun_unaligned_vmcb(void *data) +{ + struct vmcb *vmcb; + vmcb = (struct vmcb *)data; + + u64 *tmp_region; + tmp_region = (u64 *)vmcb; + tmp_region = (u64 *)((intptr_t)tmp_region + 1); + asm volatile ("vmrun" : : "a"(virt_to_phys(tmp_region))); +} + +static void vmrun_bits_beyond_pa_width(void *data) +{ + struct vmcb *vmcb; + vmcb = (struct vmcb*)data; + + u64 *tmp_region; + tmp_region = (u64 *)vmcb; + + int width = ((cpuid(0x80000008).a) & 0xff); + tmp_region = (u64 *)((intptr_t)tmp_region | ((u64)1 << (width+1))); + asm volatile ("vmrun" : : "a"(virt_to_phys(tmp_region))); +} + +static void test_vmrun_vmcb_variations() +{ + struct vmcb *vmcb; + vmcb = alloc_page(); + vmcb_ident(vmcb); + cli(); + + report("test vmrun with unaligned vmcb - #GP", + test_for_exception(GP_VECTOR, &vmrun_unaligned_vmcb, (void*)vmcb)); + + report("test vmrun with bits set beyond PA width - #GP", + test_for_exception(GP_VECTOR, &vmrun_bits_beyond_pa_width, (void*)vmcb)); +} static struct test tests[] = { { "null", default_supported, default_prepare, null_test, @@ -1192,6 +1229,11 @@ int main(int ac, const char **av) vmcb = alloc_page(); + if(test_wanted("test_vmrun_vmcb_variations", av, ac)) { + test_vmrun_vmcb_variations(); + return report_summary(); + } + nr = ARRAY_SIZE(tests); for (i = 0; i < nr; ++i) { if (!tests[i].supported()) diff --git a/x86/unittests.cfg b/x86/unittests.cfg index 19407af..0c96c29 100644 --- a/x86/unittests.cfg +++ b/x86/unittests.cfg @@ -199,6 +199,11 @@ file = svm.flat extra_params = -cpu host,+svm -append test_svm_virtual_machine_control arch = x86_64 +[svm_test_vmcb_variations] +file = svm.flat +extra_params = -cpu host,+svm -append test_vmrun_vmcb_variations +arch = x86_64 + [taskswitch] file = taskswitch.flat arch = i386 -- 2.14.3