[TEST PATCH] nSVM: Test the effect of EFLAGS.RF on guest code

[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 for EFLAGS.RF, that value takes
     effect and suppresses any potential (guest) instruction breakpoint on
     the first guest instruction."

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

diff --git a/x86/svm_tests.c b/x86/svm_tests.c
index 7827d1e..b6bb529 100644
--- a/x86/svm_tests.c
+++ b/x86/svm_tests.c
@@ -2496,14 +2496,25 @@ static void test_vmrun_canonicalization(void)
  * cause a trace trap between the VMRUN and the first guest instruction, but
  * rather after completion of the first guest instruction.
  *
+ * When VMRUN loads a guest value of 1 for EFLAGS.RF, that value takes effect
+ * and suppresses any potential (guest) instruction breakpoint on the first
+ * guest instruction.
+ *
  * [APM vol 2]
  */
 u64 guest_rflags_test_trap_rip;
+u8 guest_rflags_rf_test_counter = 0;
+bool guest_rflags_rf_test = false;
 
 static void guest_rflags_test_db_handler(struct ex_regs *r)
 {
 	guest_rflags_test_trap_rip = r->rip;
 	r->rflags &= ~X86_EFLAGS_TF;
+
+	if (guest_rflags_rf_test) {
+		++guest_rflags_rf_test_counter;
+		r->rflags |= X86_EFLAGS_RF;
+	}
 }
 
 extern void guest_rflags_test_guest(struct svm_test *test);
@@ -2542,6 +2553,7 @@ static void test_guest_rflags(void)
 	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");
+	vmcb->save.rflags &= ~X86_EFLAGS_TF;
 
 	/*
 	 * Let guest finish execution
@@ -2549,6 +2561,32 @@ static void test_guest_rflags(void)
 	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");
+
+	/*
+	 * Trap expected before first guest instruction
+	 */
+	guest_rflags_rf_test = true;
+	vmcb->save.dr7 |= 0x403;
+	write_dr0(guest_rflags_test_guest);
+	write_dr7(0x403);
+	report (__svm_vmrun((u64)guest_rflags_test_guest) == SVM_EXIT_VMMCALL &&
+		guest_rflags_rf_test_counter == 1 &&
+		guest_rflags_test_trap_rip == (u64)&guest_rflags_test_guest,
+               "Test EFLAGS.RF on guest code: trap expected before execution of first guest instruction");
+	/*
+	 * No trap expected
+	 */
+	vmcb->save.rflags |= X86_EFLAGS_RF;
+	guest_rflags_rf_test_counter = 0;
+	report (__svm_vmrun((u64)guest_rflags_test_guest) == SVM_EXIT_VMMCALL &&
+		guest_rflags_rf_test_counter == 0,
+               "Test EFLAGS.RF on guest code: trap not expected");
+
+	/*
+	 * Let guest finish execution
+	 */
+	report (__svm_vmrun((u64)&guest_end) == SVM_EXIT_VMMCALL,
+               "Test guest EFLAGS.RF: Guest execution completion");
 }
 
 static void svm_guest_state_test(void)
-- 
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