diff options
author | Krish Sadhukhan <krish.sadhukhan@oracle.com> | 2020-05-22 18:19:53 -0400 |
---|---|---|
committer | Paolo Bonzini <pbonzini@redhat.com> | 2020-07-01 12:00:04 -0400 |
commit | eae10e8f3d7fbb539af8dcfdab4df2a4f70fab05 (patch) | |
tree | ed90ebe90bee4e8b46fd8a3bc775fd8a41bc2a9a | |
parent | 84a43d344a5c70df847521b2a4e1a736ca97d922 (diff) | |
download | kvm-unit-tests-eae10e8f3d7fbb539af8dcfdab4df2a4f70fab05.tar.gz |
kvm-unit-tests: nSVM: Test that DR6[63:32], DR7[63:32] and EFER reserved bits are not set on vmrun of nested guests
According to section "Canonicalization and Consistency Checks" in APM vol. 2
the following guest state is illegal:
"DR6[63:32] are not zero."
"DR7[63:32] are not zero."
"Any MBZ bit of EFER is set."
Signed-off-by: Krish Sadhukhan <krish.sadhukhan@oracle.com>
Message-Id: <20200522221954.32131-4-krish.sadhukhan@oracle.com>
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
-rw-r--r-- | x86/svm.h | 5 | ||||
-rw-r--r-- | x86/svm_tests.c | 56 |
2 files changed, 53 insertions, 8 deletions
@@ -324,6 +324,11 @@ struct __attribute__ ((__packed__)) vmcb { #define SVM_CR0_SELECTIVE_MASK (X86_CR0_TS | X86_CR0_MP) +#define SVM_CR0_RESERVED_MASK 0xffffffff00000000U +#define SVM_DR6_RESERVED_MASK 0xffffffffffff1ff0U +#define SVM_DR7_RESERVED_MASK 0xffffffff0000cc00U +#define SVM_EFER_RESERVED_MASK 0xffffffffffff0200U + #define MSR_BITMAP_SIZE 8192 struct svm_test { diff --git a/x86/svm_tests.c b/x86/svm_tests.c index 48f2d8e..d4d130f 100644 --- a/x86/svm_tests.c +++ b/x86/svm_tests.c @@ -1895,6 +1895,24 @@ static void basic_guest_main(struct svm_test *test) { } + +#define SVM_TEST_REG_RESERVED_BITS(start, end, inc, str_name, reg, val, \ + resv_mask) \ +{ \ + u64 tmp, mask; \ + int i; \ + \ + for (i = start; i <= end; i = i + inc) { \ + mask = 1ull << i; \ + if (!(mask & resv_mask)) \ + continue; \ + tmp = val | mask; \ + reg = tmp; \ + report(svm_vmrun() == SVM_EXIT_ERR, "Test %s %d:%d: %lx",\ + str_name, end, start, tmp); \ + } \ +} + static void svm_guest_state_test(void) { test_set_guest(basic_guest_main); @@ -1936,16 +1954,38 @@ static void svm_guest_state_test(void) /* * CR0[63:32] are not zero */ - int i; - cr0 = cr0_saved; - for (i = 32; i < 63; i = i + 4) { - cr0 = cr0_saved | (1ull << i); - vmcb->save.cr0 = cr0; - report (svm_vmrun() == SVM_EXIT_ERR, "CR0[63:32]: %lx", - cr0 >> 32); - } + + SVM_TEST_REG_RESERVED_BITS(32, 63, 4, "CR0", vmcb->save.cr0, cr0_saved, + SVM_CR0_RESERVED_MASK); vmcb->save.cr0 = cr0_saved; + + /* + * DR6[63:32] and DR7[63:32] are MBZ + */ + u64 dr_saved = vmcb->save.dr6; + + SVM_TEST_REG_RESERVED_BITS(32, 63, 4, "DR6", vmcb->save.dr6, dr_saved, + SVM_DR6_RESERVED_MASK); + vmcb->save.dr6 = dr_saved; + + dr_saved = vmcb->save.dr7; + SVM_TEST_REG_RESERVED_BITS(32, 63, 4, "DR7", vmcb->save.dr7, dr_saved, + SVM_DR7_RESERVED_MASK); + + vmcb->save.dr7 = dr_saved; + + /* + * EFER MBZ bits: 63:16, 9 + */ + efer_saved = vmcb->save.efer; + + SVM_TEST_REG_RESERVED_BITS(8, 9, 1, "EFER", vmcb->save.efer, + efer_saved, SVM_EFER_RESERVED_MASK); + SVM_TEST_REG_RESERVED_BITS(16, 63, 4, "EFER", vmcb->save.efer, + efer_saved, SVM_EFER_RESERVED_MASK); + + vmcb->save.efer = efer_saved; } struct svm_test svm_tests[] = { |