[PATCH 1/2] svm: Add VMRUN/VMEXIT latency test

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

 



This patch adds a test to measure the latency of VMRUN and
VMEXIT.

Signed-off-by: Joerg Roedel <joerg.roedel@xxxxxxx>
---
 x86/svm.c |   81 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
 1 files changed, 81 insertions(+), 0 deletions(-)

diff --git a/x86/svm.c b/x86/svm.c
index dc3098f..babd77d 100644
--- a/x86/svm.c
+++ b/x86/svm.c
@@ -13,6 +13,18 @@ u64 *pde[4];
 u64 *pte[2048];
 u64 *scratch_page;
 
+#define LATENCY_RUNS 1000000
+
+u64 tsc_start;
+u64 tsc_end;
+
+u64 vmrun_sum, vmexit_sum;
+u64 latvmrun_max;
+u64 latvmrun_min;
+u64 latvmexit_max;
+u64 latvmexit_min;
+u64 runs;
+
 static bool npt_supported(void)
 {
    return cpuid(0x8000000A).d & 1;
@@ -162,6 +174,7 @@ static bool test_run(struct test *test, struct vmcb *vmcb)
     vmcb->save.rip = (ulong)test_thunk;
     vmcb->save.rsp = (ulong)(guest_stack + ARRAY_SIZE(guest_stack));
     do {
+        tsc_start = rdtsc();
         asm volatile (
             "clgi \n\t"
             "vmload \n\t"
@@ -176,9 +189,11 @@ static bool test_run(struct test *test, struct vmcb *vmcb)
             : "rbx", "rcx", "rdx", "rsi",
               "r8", "r9", "r10", "r11" , "r12", "r13", "r14", "r15",
               "memory");
+	tsc_end = rdtsc();
         ++test->exits;
     } while (!test->finished(test));
 
+
     success = test->succeeded(test);
 
     printf("%s: %s\n", test->name, success ? "PASS" : "FAIL");
@@ -582,6 +597,70 @@ static bool npt_pfwalk_check(struct test *test)
 	   && (test->vmcb->control.exit_info_2 == read_cr3());
 }
 
+static void latency_prepare(struct test *test)
+{
+    default_prepare(test);
+    runs = LATENCY_RUNS;
+    latvmrun_min = latvmexit_min = -1ULL;
+    latvmrun_max = latvmexit_max = 0;
+    vmrun_sum = vmexit_sum = 0;
+}
+
+static void latency_test(struct test *test)
+{
+    u64 cycles;
+
+start:
+    tsc_end = rdtsc();
+
+    cycles = tsc_end - tsc_start;
+
+    if (cycles > latvmrun_max)
+        latvmrun_max = cycles;
+
+    if (cycles < latvmrun_min)
+        latvmrun_min = cycles;
+
+    vmrun_sum += cycles;
+
+    tsc_start = rdtsc();
+
+    asm volatile ("vmmcall" : : : "memory");
+    goto start;
+}
+
+static bool latency_finished(struct test *test)
+{
+    u64 cycles;
+
+    tsc_end = rdtsc();
+
+    cycles = tsc_end - tsc_start;
+
+    if (cycles > latvmexit_max)
+        latvmexit_max = cycles;
+
+    if (cycles < latvmexit_min)
+        latvmexit_min = cycles;
+
+    vmexit_sum += cycles;
+
+    test->vmcb->save.rip += 3;
+
+    runs -= 1;
+
+    return runs == 0;
+}
+
+static bool latency_check(struct test *test)
+{
+    printf("    Latency VMRUN : max: %d min: %d avg: %d\n", latvmrun_max,
+            latvmrun_min, vmrun_sum / LATENCY_RUNS);
+    printf("    Latency VMEXIT: max: %d min: %d avg: %d\n", latvmexit_max,
+            latvmexit_min, vmexit_sum / LATENCY_RUNS);
+    return true;
+}
+
 static struct test tests[] = {
     { "null", default_supported, default_prepare, null_test,
       default_finished, null_check },
@@ -614,6 +693,8 @@ static struct test tests[] = {
 	    default_finished, npt_rw_check },
     { "npt_pfwalk", npt_supported, npt_pfwalk_prepare, null_test,
 	    default_finished, npt_pfwalk_check },
+    { "latency_run_exit", default_supported, latency_prepare, latency_test,
+      latency_finished, latency_check },
 };
 
 int main(int ac, char **av)
-- 
1.7.0.4


--
To unsubscribe from this list: send the line "unsubscribe kvm" in
the body of a message to majordomo@xxxxxxxxxxxxxxx
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[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