[PATCH 2/2 v2] Test: nSVM: Test the effect of guest EFLAGS.TF on VMRUN

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



According to section "VMRUN and TF/RF Bits in EFLAGS." in APM vol 2,

     "When VMRUN loads a guest value of 1 in EFLAGS.TF, that value does not
      cause a trace trap between the VMRUN and the first guest instruction,
      but rather after completion of the first guest instruction."

Signed-off-by: Krish Sadhukhan <krish.sadhukhan@xxxxxxxxxx>
---
 x86/svm_tests.c | 61 +++++++++++++++++++++++++++++++++++++++++++++++++
 1 file changed, 61 insertions(+)

diff --git a/x86/svm_tests.c b/x86/svm_tests.c
index a56a197..7827d1e 100644
--- a/x86/svm_tests.c
+++ b/x86/svm_tests.c
@@ -2491,6 +2491,66 @@ static void test_vmrun_canonicalization(void)
 	TEST_CANONICAL(vmcb->save.tr.base, "TR");
 }
 
+/*
+ * When VMRUN loads a guest value of 1 in EFLAGS.TF, that value does not
+ * cause a trace trap between the VMRUN and the first guest instruction, but
+ * rather after completion of the first guest instruction.
+ *
+ * [APM vol 2]
+ */
+u64 guest_rflags_test_trap_rip;
+
+static void guest_rflags_test_db_handler(struct ex_regs *r)
+{
+	guest_rflags_test_trap_rip = r->rip;
+	r->rflags &= ~X86_EFLAGS_TF;
+}
+
+extern void guest_rflags_test_guest(struct svm_test *test);
+extern u64 *insn2;
+extern u64 *guest_end;
+
+asm("guest_rflags_test_guest:\n\t"
+    "push %rbp\n\t"
+    ".global insn2\n\t"
+    "insn2:\n\t"
+    "mov %rsp,%rbp\n\t"
+    "vmmcall\n\t"
+    "vmmcall\n\t"
+    ".global guest_end\n\t"
+    "guest_end:\n\t"
+    "vmmcall\n\t"
+    "pop %rbp\n\t"
+    "ret");
+
+static void test_guest_rflags(void)
+{
+	handle_exception(DB_VECTOR, guest_rflags_test_db_handler);
+
+	/*
+	 * Trap expected after completion of first guest instruction
+	 */
+	vmcb->save.rflags |= X86_EFLAGS_TF;
+	report (__svm_vmrun((u64)guest_rflags_test_guest) == SVM_EXIT_VMMCALL &&
+		guest_rflags_test_trap_rip == (u64)&insn2,
+               "Test EFLAGS.TF on VMRUN: trap expected  after completion of first guest instruction");
+	/*
+	 * No trap expected
+	 */
+	guest_rflags_test_trap_rip = 0;
+	vmcb->save.rip += 3;
+	vmcb->save.rflags |= X86_EFLAGS_TF;
+	report (__svm_vmrun(vmcb->save.rip) == SVM_EXIT_VMMCALL &&
+		guest_rflags_test_trap_rip == 0, "Test EFLAGS.TF on VMRUN: trap not expected");
+
+	/*
+	 * Let guest finish execution
+	 */
+	vmcb->save.rip += 3;
+	report (__svm_vmrun(vmcb->save.rip) == SVM_EXIT_VMMCALL &&
+		vmcb->save.rip == (u64)&guest_end, "Test EFLAGS.TF on VMRUN: guest execution completion");
+}
+
 static void svm_guest_state_test(void)
 {
 	test_set_guest(basic_guest_main);
@@ -2501,6 +2561,7 @@ static void svm_guest_state_test(void)
 	test_dr();
 	test_msrpm_iopm_bitmap_addrs();
 	test_vmrun_canonicalization();
+	test_guest_rflags();
 }
 
 static void __svm_npt_rsvd_bits_test(u64 *pxe, u64 rsvd_bits, u64 efer,
-- 
2.27.0




[Index of Archives]     [KVM ARM]     [KVM ia64]     [KVM ppc]     [Virtualization Tools]     [Spice Development]     [Libvirt]     [Libvirt Users]     [Linux USB Devel]     [Linux Audio Users]     [Yosemite Questions]     [Linux Kernel]     [Linux SCSI]     [XFree86]

  Powered by Linux