[TEST PATCH] nSVM: Test the effect of EFLAGS.RF on guest code
From: Krish Sadhukhan <hidden>
Date: 2021-08-04 19:15:09
Subsystem:
the rest · Maintainer:
Linus Torvalds
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 <redacted>
---
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