All of lore.kernel.org
 help / color / mirror / Atom feed
From: Paolo Bonzini <pbonzini@redhat.com>
To: kvm@vger.kernel.org
Cc: cavery@redhat.com
Subject: [PATCH kvm-unit-tests 1/2] svm: introduce prepare_gif_clear callback
Date: Wed, 18 Dec 2019 18:33:02 +0100	[thread overview]
Message-ID: <1576690383-16170-2-git-send-email-pbonzini@redhat.com> (raw)
In-Reply-To: <1576690383-16170-1-git-send-email-pbonzini@redhat.com>

Generalize the set_host_if flag that was added recently, by introducing
a new callback that is called with GIF=0 && IF=1.  This is useful to
inject events that will trigger right after VMRUN.

Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
---
 x86/svm.c | 124 ++++++++++++++++++++++++++++++++++++++++----------------------
 1 file changed, 81 insertions(+), 43 deletions(-)

diff --git a/x86/svm.c b/x86/svm.c
index 99b1d71..63fda65 100644
--- a/x86/svm.c
+++ b/x86/svm.c
@@ -192,6 +192,7 @@ struct test {
     const char *name;
     bool (*supported)(void);
     void (*prepare)(struct test *test);
+    void (*prepare_gif_clear)(struct test *test);
     void (*guest_func)(struct test *test);
     bool (*finished)(struct test *test);
     bool (*succeeded)(struct test *test);
@@ -266,31 +267,37 @@ static void test_run(struct test *test, struct vmcb *vmcb)
     vmcb->save.rsp = (ulong)(guest_stack + ARRAY_SIZE(guest_stack));
     regs.rdi = (ulong)test;
     do {
+        struct test *the_test = test;
+        u64 the_vmcb = vmcb_phys;
         tsc_start = rdtsc();
         asm volatile (
             "clgi;\n\t" // semi-colon needed for LLVM compatibility
-            "cmpb $0, set_host_if\n\t"
-            "jz 1f\n\t"
             "sti \n\t"
-            "1: \n\t"
+            "call *%c[PREPARE_GIF_CLEAR](%[test]) \n \t"
+            "mov %[vmcb_phys], %%rax \n\t"
             "vmload \n\t"
             "vmload %0\n\t"
             "mov regs+0x80, %%r15\n\t"  // rflags
-            "mov %%r15, 0x170(%0)\n\t"
+            "mov %%r15, 0x170(%%rax)\n\t"
             "mov regs, %%r15\n\t"       // rax
-            "mov %%r15, 0x1f8(%0)\n\t"
+            "mov %%r15, 0x1f8(%%rax)\n\t"
             LOAD_GPR_C
             "vmrun %0\n\t"
             SAVE_GPR_C
-            "mov 0x170(%0), %%r15\n\t"  // rflags
+            "mov 0x170(%%rax), %%r15\n\t"  // rflags
             "mov %%r15, regs+0x80\n\t"
-            "mov 0x1f8(%0), %%r15\n\t"  // rax
+            "mov 0x1f8(%%rax), %%r15\n\t"  // rax
             "mov %%r15, regs\n\t"
             "vmsave %0\n\t"
             "cli \n\t"
             "stgi"
-            : : "a"(vmcb_phys)
-            : "rbx", "rcx", "rdx", "rsi",
+            : // inputs clobbered by the guest:
+	      "+D" (the_test),            // first argument register
+	      "+b" (the_vmcb)             // callee save register!
+            : [test] "0" (the_test),
+	      [vmcb_phys] "1"(the_vmcb),
+	      [PREPARE_GIF_CLEAR] "i" (offsetof(struct test, prepare_gif_clear))
+            : "rax", "rcx", "rdx", "rsi",
               "r8", "r9", "r10", "r11" , "r12", "r13", "r14", "r15",
               "memory");
 	tsc_end = rdtsc();
@@ -316,6 +323,12 @@ static void default_prepare(struct test *test)
     vmcb_ident(test->vmcb);
 }
 
+static void default_prepare_gif_clear(struct test *test)
+{
+    if (!set_host_if)
+        asm("cli");
+}
+
 static bool default_finished(struct test *test)
 {
     return true; /* one vmexit */
@@ -1486,58 +1499,83 @@ static bool pending_event_check_vmask(struct test *test)
 }
 
 static struct test tests[] = {
-    { "null", default_supported, default_prepare, null_test,
+    { "null", default_supported, default_prepare,
+      default_prepare_gif_clear, null_test,
       default_finished, null_check },
-    { "vmrun", default_supported, default_prepare, test_vmrun,
+    { "vmrun", default_supported, default_prepare,
+      default_prepare_gif_clear, test_vmrun,
        default_finished, check_vmrun },
-    { "ioio", default_supported, prepare_ioio, test_ioio,
+    { "ioio", default_supported, prepare_ioio,
+       default_prepare_gif_clear, test_ioio,
        ioio_finished, check_ioio },
     { "vmrun intercept check", default_supported, prepare_no_vmrun_int,
-      null_test, default_finished, check_no_vmrun_int },
-    { "cr3 read intercept", default_supported, prepare_cr3_intercept,
+      default_prepare_gif_clear, null_test, default_finished,
+      check_no_vmrun_int },
+    { "cr3 read intercept", default_supported,
+      prepare_cr3_intercept, default_prepare_gif_clear,
       test_cr3_intercept, default_finished, check_cr3_intercept },
     { "cr3 read nointercept", default_supported, default_prepare,
-      test_cr3_intercept, default_finished, check_cr3_nointercept },
+      default_prepare_gif_clear, test_cr3_intercept, default_finished,
+      check_cr3_nointercept },
     { "cr3 read intercept emulate", smp_supported,
-      prepare_cr3_intercept_bypass, test_cr3_intercept_bypass,
-      default_finished, check_cr3_intercept },
+      prepare_cr3_intercept_bypass, default_prepare_gif_clear,
+      test_cr3_intercept_bypass, default_finished, check_cr3_intercept },
     { "dr intercept check", default_supported, prepare_dr_intercept,
-      test_dr_intercept, dr_intercept_finished, check_dr_intercept },
-    { "next_rip", next_rip_supported, prepare_next_rip, test_next_rip,
+      default_prepare_gif_clear, test_dr_intercept, dr_intercept_finished,
+      check_dr_intercept },
+    { "next_rip", next_rip_supported, prepare_next_rip,
+      default_prepare_gif_clear, test_next_rip,
       default_finished, check_next_rip },
     { "msr intercept check", default_supported, prepare_msr_intercept,
-       test_msr_intercept, msr_intercept_finished, check_msr_intercept },
-    { "mode_switch", default_supported, prepare_mode_switch, test_mode_switch,
+      default_prepare_gif_clear, test_msr_intercept,
+      msr_intercept_finished, check_msr_intercept },
+    { "mode_switch", default_supported, prepare_mode_switch,
+      default_prepare_gif_clear, test_mode_switch,
        mode_switch_finished, check_mode_switch },
-    { "asid_zero", default_supported, prepare_asid_zero, test_asid_zero,
+    { "asid_zero", default_supported, prepare_asid_zero,
+      default_prepare_gif_clear, test_asid_zero,
        default_finished, check_asid_zero },
-    { "sel_cr0_bug", default_supported, sel_cr0_bug_prepare, sel_cr0_bug_test,
+    { "sel_cr0_bug", default_supported, sel_cr0_bug_prepare,
+      default_prepare_gif_clear, sel_cr0_bug_test,
        sel_cr0_bug_finished, sel_cr0_bug_check },
-    { "npt_nx", npt_supported, npt_nx_prepare, null_test,
-	    default_finished, npt_nx_check },
-    { "npt_us", npt_supported, npt_us_prepare, npt_us_test,
-	    default_finished, npt_us_check },
-    { "npt_rsvd", npt_supported, npt_rsvd_prepare, null_test,
-	    default_finished, npt_rsvd_check },
-    { "npt_rw", npt_supported, npt_rw_prepare, npt_rw_test,
-	    default_finished, npt_rw_check },
-    { "npt_rsvd_pfwalk", npt_supported, npt_rsvd_pfwalk_prepare, null_test,
-	    default_finished, npt_rsvd_pfwalk_check },
-    { "npt_rw_pfwalk", npt_supported, npt_rw_pfwalk_prepare, null_test,
-	    default_finished, npt_rw_pfwalk_check },
-    { "npt_l1mmio", npt_supported, npt_l1mmio_prepare, npt_l1mmio_test,
-	    default_finished, npt_l1mmio_check },
-    { "npt_rw_l1mmio", npt_supported, npt_rw_l1mmio_prepare, npt_rw_l1mmio_test,
-	    default_finished, npt_rw_l1mmio_check },
-    { "tsc_adjust", default_supported, tsc_adjust_prepare, tsc_adjust_test,
-       default_finished, tsc_adjust_check },
-    { "latency_run_exit", default_supported, latency_prepare, latency_test,
+    { "npt_nx", npt_supported, npt_nx_prepare,
+      default_prepare_gif_clear, null_test,
+      default_finished, npt_nx_check },
+    { "npt_us", npt_supported, npt_us_prepare,
+      default_prepare_gif_clear, npt_us_test,
+      default_finished, npt_us_check },
+    { "npt_rsvd", npt_supported, npt_rsvd_prepare,
+      default_prepare_gif_clear, null_test,
+      default_finished, npt_rsvd_check },
+    { "npt_rw", npt_supported, npt_rw_prepare,
+      default_prepare_gif_clear, npt_rw_test,
+      default_finished, npt_rw_check },
+    { "npt_rsvd_pfwalk", npt_supported, npt_rsvd_pfwalk_prepare,
+      default_prepare_gif_clear, null_test,
+      default_finished, npt_rsvd_pfwalk_check },
+    { "npt_rw_pfwalk", npt_supported, npt_rw_pfwalk_prepare,
+      default_prepare_gif_clear, null_test,
+      default_finished, npt_rw_pfwalk_check },
+    { "npt_l1mmio", npt_supported, npt_l1mmio_prepare,
+      default_prepare_gif_clear, npt_l1mmio_test,
+      default_finished, npt_l1mmio_check },
+    { "npt_rw_l1mmio", npt_supported, npt_rw_l1mmio_prepare,
+      default_prepare_gif_clear, npt_rw_l1mmio_test,
+      default_finished, npt_rw_l1mmio_check },
+    { "tsc_adjust", default_supported, tsc_adjust_prepare,
+      default_prepare_gif_clear, tsc_adjust_test,
+      default_finished, tsc_adjust_check },
+    { "latency_run_exit", default_supported, latency_prepare,
+      default_prepare_gif_clear, latency_test,
       latency_finished, latency_check },
-    { "latency_svm_insn", default_supported, lat_svm_insn_prepare, null_test,
+    { "latency_svm_insn", default_supported, lat_svm_insn_prepare,
+      default_prepare_gif_clear, null_test,
       lat_svm_insn_finished, lat_svm_insn_check },
     { "pending_event", default_supported, pending_event_prepare,
+      default_prepare_gif_clear,
       pending_event_test, pending_event_finished, pending_event_check },
     { "pending_event_vmask", default_supported, pending_event_prepare_vmask,
+      default_prepare_gif_clear,
       pending_event_test_vmask, pending_event_finished_vmask,
       pending_event_check_vmask },
 };
-- 
1.8.3.1



  reply	other threads:[~2019-12-18 17:33 UTC|newest]

Thread overview: 3+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2019-12-18 17:33 [PATCH kvm-unit-tests 0/2] svm: make preparation more flexible Paolo Bonzini
2019-12-18 17:33 ` Paolo Bonzini [this message]
2019-12-18 17:33 ` [PATCH kvm-unit-tests 2/2] svm: replace set_host_if with prepare_gif_clear callback Paolo Bonzini

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=1576690383-16170-2-git-send-email-pbonzini@redhat.com \
    --to=pbonzini@redhat.com \
    --cc=cavery@redhat.com \
    --cc=kvm@vger.kernel.org \
    /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 an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.