From: Maxim Levitsky <mlevitsk@redhat.com>
To: kvm@vger.kernel.org
Cc: "Andrew Jones" <drjones@redhat.com>,
"Alexandru Elisei" <alexandru.elisei@arm.com>,
"Maxim Levitsky" <mlevitsk@redhat.com>,
"Paolo Bonzini" <pbonzini@redhat.com>,
"Claudio Imbrenda" <imbrenda@linux.ibm.com>,
"Thomas Huth" <thuth@redhat.com>,
"Alex Bennée" <alex.bennee@linaro.org>,
"Nico Boehr" <nrb@linux.ibm.com>,
"Cathy Avery" <cavery@redhat.com>,
"Janosch Frank" <frankja@linux.ibm.com>
Subject: [kvm-unit-tests PATCH v3 10/27] SVM: add two tests for exitintinto on exception
Date: Tue, 22 Nov 2022 18:11:35 +0200 [thread overview]
Message-ID: <20221122161152.293072-11-mlevitsk@redhat.com> (raw)
In-Reply-To: <20221122161152.293072-1-mlevitsk@redhat.com>
Test that exitintinfo is set correctly when
exception happens during exception/interrupt delivery
and that exception is intercepted.
Note that those tests currently fail, due to few bugs in KVM.
Also note that those bugs are in KVM's common x86 code,
thus the issue exists on VMX as well and unit tests
that reproduce those on VMX will be written as well.
Signed-off-by: Maxim Levitsky <mlevitsk@redhat.com>
---
x86/svm_tests.c | 148 ++++++++++++++++++++++++++++++++++++++++++++++++
1 file changed, 148 insertions(+)
diff --git a/x86/svm_tests.c b/x86/svm_tests.c
index 7a67132a..202e9271 100644
--- a/x86/svm_tests.c
+++ b/x86/svm_tests.c
@@ -3254,6 +3254,145 @@ static void svm_shutdown_intercept_test(void)
report(vmcb->control.exit_code == SVM_EXIT_SHUTDOWN, "shutdown test passed");
}
+/*
+ * Test that nested exceptions are delivered correctly
+ * when parent exception is intercepted
+ */
+
+static void exception_merging_prepare(struct svm_test *test)
+{
+ vmcb->control.intercept_exceptions |= (1ULL << GP_VECTOR);
+
+ /* break UD vector idt entry to get #GP*/
+ boot_idt[UD_VECTOR].type = 1;
+}
+
+static void exception_merging_test(struct svm_test *test)
+{
+ asm volatile ("ud2");
+}
+
+static bool exception_merging_finished(struct svm_test *test)
+{
+ u32 vec = vmcb->control.exit_int_info & SVM_EXITINTINFO_VEC_MASK;
+ u32 type = vmcb->control.exit_int_info & SVM_EXITINTINFO_TYPE_MASK;
+
+ if (vmcb->control.exit_code != SVM_EXIT_EXCP_BASE + GP_VECTOR) {
+ report(false, "unexpected VM exit");
+ goto out;
+ }
+
+ if (!(vmcb->control.exit_int_info & SVM_EXITINTINFO_VALID)) {
+ report(false, "EXITINTINFO not valid");
+ goto out;
+ }
+
+ if (type != SVM_EXITINTINFO_TYPE_EXEPT) {
+ report(false, "Incorrect event type in EXITINTINFO");
+ goto out;
+ }
+
+ if (vec != UD_VECTOR) {
+ report(false, "Incorrect vector in EXITINTINFO");
+ goto out;
+ }
+
+ set_test_stage(test, 1);
+out:
+ boot_idt[UD_VECTOR].type = 14;
+ return true;
+}
+
+static bool exception_merging_check(struct svm_test *test)
+{
+ return get_test_stage(test) == 1;
+}
+
+
+/*
+ * Test that if exception is raised during interrupt delivery,
+ * and that exception is intercepted, the interrupt is preserved
+ * in EXITINTINFO of the exception
+ */
+
+static void interrupt_merging_prepare(struct svm_test *test)
+{
+ /* intercept #GP */
+ vmcb->control.intercept_exceptions |= (1ULL << GP_VECTOR);
+
+ /* set local APIC to inject external interrupts */
+ apic_setup_timer(TIMER_VECTOR, APIC_LVT_TIMER_PERIODIC);
+ apic_start_timer(100000);
+}
+
+#define INTERRUPT_MERGING_DELAY 100000000ULL
+
+static void interrupt_merging_test(struct svm_test *test)
+{
+ handle_irq(TIMER_VECTOR, timer_isr);
+ /* break timer vector IDT entry to get #GP on interrupt delivery */
+ boot_idt[TIMER_VECTOR].type = 1;
+
+ sti();
+ delay(INTERRUPT_MERGING_DELAY);
+}
+
+static bool interrupt_merging_finished(struct svm_test *test)
+{
+
+ u32 vec = vmcb->control.exit_int_info & SVM_EXITINTINFO_VEC_MASK;
+ u32 type = vmcb->control.exit_int_info & SVM_EXITINTINFO_TYPE_MASK;
+ u32 error_code = vmcb->control.exit_info_1;
+
+ /* exit on external interrupts is disabled, thus timer interrupt
+ * should be attempted to be delivered, but due to incorrect IDT entry
+ * an #GP should be raised
+ */
+ if (vmcb->control.exit_code != SVM_EXIT_EXCP_BASE + GP_VECTOR) {
+ report(false, "unexpected VM exit");
+ goto cleanup;
+ }
+
+ /* GP error code should be about an IDT entry, and due to external event */
+ if (error_code != (TIMER_VECTOR << 3 | 3)) {
+ report(false, "Incorrect error code of the GP exception");
+ goto cleanup;
+ }
+
+ /* Original interrupt should be preserved in EXITINTINFO */
+ if (!(vmcb->control.exit_int_info & SVM_EXITINTINFO_VALID)) {
+ report(false, "EXITINTINFO not valid");
+ goto cleanup;
+ }
+
+ if (type != SVM_EXITINTINFO_TYPE_INTR) {
+ report(false, "Incorrect event type in EXITINTINFO");
+ goto cleanup;
+ }
+
+ if (vec != TIMER_VECTOR) {
+ report(false, "Incorrect vector in EXITINTINFO");
+ goto cleanup;
+ }
+
+ set_test_stage(test, 1);
+
+cleanup:
+ // restore the IDT gate
+ boot_idt[TIMER_VECTOR].type = 14;
+ wmb();
+ // eoi the interrupt we got #GP for
+ eoi();
+ apic_cleanup_timer();
+ return true;
+}
+
+static bool interrupt_merging_check(struct svm_test *test)
+{
+ return get_test_stage(test) == 1;
+}
+
+
struct svm_test svm_tests[] = {
{ "null", default_supported, default_prepare,
default_prepare_gif_clear, null_test,
@@ -3346,6 +3485,15 @@ struct svm_test svm_tests[] = {
{ "vgif", vgif_supported, prepare_vgif_enabled,
default_prepare_gif_clear, test_vgif, vgif_finished,
vgif_check },
+ { "exception_merging", default_supported,
+ exception_merging_prepare, default_prepare_gif_clear,
+ exception_merging_test, exception_merging_finished,
+ exception_merging_check },
+ { "interrupt_merging", default_supported,
+ interrupt_merging_prepare, default_prepare_gif_clear,
+ interrupt_merging_test, interrupt_merging_finished,
+ interrupt_merging_check },
+
TEST(svm_cr4_osxsave_test),
TEST(svm_guest_state_test),
TEST(svm_vmrun_errata_test),
--
2.34.3
next prev parent reply other threads:[~2022-11-22 16:15 UTC|newest]
Thread overview: 56+ messages / expand[flat|nested] mbox.gz Atom feed top
2022-11-22 16:11 [kvm-unit-tests PATCH v3 00/27] kvm-unit-tests: set of fixes and new tests Maxim Levitsky
2022-11-22 16:11 ` [kvm-unit-tests PATCH v3 01/27] x86: replace irq_{enable|disable}() with sti()/cli() Maxim Levitsky
2022-12-01 13:46 ` Emanuele Giuseppe Esposito
2022-12-06 13:55 ` Maxim Levitsky
2022-12-06 14:15 ` Emanuele Giuseppe Esposito
2022-11-22 16:11 ` [kvm-unit-tests PATCH v3 02/27] x86: introduce sti_nop() and sti_nop_cli() Maxim Levitsky
2022-12-01 13:46 ` Emanuele Giuseppe Esposito
2022-11-22 16:11 ` [kvm-unit-tests PATCH v3 03/27] x86: add few helper functions for apic local timer Maxim Levitsky
2022-11-22 16:11 ` [kvm-unit-tests PATCH v3 04/27] svm: remove nop after stgi/clgi Maxim Levitsky
2022-11-22 16:11 ` [kvm-unit-tests PATCH v3 05/27] svm: make svm_intr_intercept_mix_if/gif test a bit more robust Maxim Levitsky
2022-11-22 16:11 ` [kvm-unit-tests PATCH v3 06/27] svm: use apic_start_timer/apic_stop_timer instead of open coding it Maxim Levitsky
2022-11-22 16:11 ` [kvm-unit-tests PATCH v3 07/27] x86: Add test for #SMI during interrupt window Maxim Levitsky
2022-11-22 16:11 ` [kvm-unit-tests PATCH v3 08/27] x86: Add a simple test for SYSENTER instruction Maxim Levitsky
2022-11-22 16:11 ` [kvm-unit-tests PATCH v3 09/27] svm: add simple nested shutdown test Maxim Levitsky
2022-12-01 13:46 ` Emanuele Giuseppe Esposito
2022-12-06 13:56 ` Maxim Levitsky
2022-11-22 16:11 ` Maxim Levitsky [this message]
2022-11-22 16:11 ` [kvm-unit-tests PATCH v3 11/27] lib: Add random number generator Maxim Levitsky
2022-11-23 9:28 ` Claudio Imbrenda
2022-11-23 12:54 ` Andrew Jones
2022-12-06 13:57 ` Maxim Levitsky
2022-12-06 14:07 ` Maxim Levitsky
2022-12-14 10:33 ` Claudio Imbrenda
2022-11-22 16:11 ` [kvm-unit-tests PATCH v3 12/27] x86: add IPI stress test Maxim Levitsky
2022-11-22 16:11 ` [kvm-unit-tests PATCH v3 13/27] svm: remove get_npt_pte extern Maxim Levitsky
2022-12-01 13:46 ` Emanuele Giuseppe Esposito
2022-11-22 16:11 ` [kvm-unit-tests PATCH v3 14/27] svm: move svm spec definitions to lib/x86/svm.h Maxim Levitsky
2022-12-01 13:54 ` Emanuele Giuseppe Esposito
2022-11-22 16:11 ` [kvm-unit-tests PATCH v3 15/27] svm: move some svm support functions into lib/x86/svm_lib.h Maxim Levitsky
2022-12-01 13:59 ` Emanuele Giuseppe Esposito
2022-12-06 14:10 ` Maxim Levitsky
2022-11-22 16:11 ` [kvm-unit-tests PATCH v3 16/27] svm: move setup_svm() to svm_lib.c Maxim Levitsky
2022-12-01 16:14 ` Emanuele Giuseppe Esposito
2022-11-22 16:11 ` [kvm-unit-tests PATCH v3 17/27] svm: correctly skip if NPT not supported Maxim Levitsky
2022-11-22 16:11 ` [kvm-unit-tests PATCH v3 18/27] svm: move vmcb_ident to svm_lib.c Maxim Levitsky
2022-12-01 16:18 ` Emanuele Giuseppe Esposito
2022-12-06 14:11 ` Maxim Levitsky
2022-11-22 16:11 ` [kvm-unit-tests PATCH v3 19/27] svm: rewerite vm entry macros Maxim Levitsky
2022-12-02 10:14 ` Emanuele Giuseppe Esposito
2022-12-06 13:56 ` Maxim Levitsky
2022-11-22 16:11 ` [kvm-unit-tests PATCH v3 20/27] svm: move v2 tests run into test_run Maxim Levitsky
2022-12-02 9:53 ` Emanuele Giuseppe Esposito
2022-11-22 16:11 ` [kvm-unit-tests PATCH v3 21/27] svm: cleanup the default_prepare Maxim Levitsky
2022-12-02 9:45 ` Emanuele Giuseppe Esposito
2022-12-06 13:56 ` Maxim Levitsky
2022-11-22 16:11 ` [kvm-unit-tests PATCH v3 22/27] svm: introduce svm_vcpu Maxim Levitsky
2022-11-22 16:11 ` [kvm-unit-tests PATCH v3 23/27] svm: introduce struct svm_test_context Maxim Levitsky
2022-11-22 16:11 ` [kvm-unit-tests PATCH v3 24/27] svm: use svm_test_context in v2 tests Maxim Levitsky
2022-12-02 10:27 ` Emanuele Giuseppe Esposito
2022-11-22 16:11 ` [kvm-unit-tests PATCH v3 25/27] svm: move nested vcpu to test context Maxim Levitsky
2022-12-02 10:22 ` Emanuele Giuseppe Esposito
2022-12-06 14:29 ` Maxim Levitsky
2022-11-22 16:11 ` [kvm-unit-tests PATCH v3 26/27] svm: move test_guest_func " Maxim Levitsky
2022-12-02 10:28 ` Emanuele Giuseppe Esposito
2022-11-22 16:11 ` [kvm-unit-tests PATCH v3 27/27] x86: ipi_stress: add optional SVM support Maxim Levitsky
2023-06-07 23:25 ` [kvm-unit-tests PATCH v3 00/27] kvm-unit-tests: set of fixes and new tests Sean Christopherson
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20221122161152.293072-11-mlevitsk@redhat.com \
--to=mlevitsk@redhat.com \
--cc=alex.bennee@linaro.org \
--cc=alexandru.elisei@arm.com \
--cc=cavery@redhat.com \
--cc=drjones@redhat.com \
--cc=frankja@linux.ibm.com \
--cc=imbrenda@linux.ibm.com \
--cc=kvm@vger.kernel.org \
--cc=nrb@linux.ibm.com \
--cc=pbonzini@redhat.com \
--cc=thuth@redhat.com \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox