Adding vmexits to proc.
authorGanShun <ganshun@gmail.com>
Tue, 29 Sep 2015 22:20:20 +0000 (15:20 -0700)
committerBarret Rhoden <brho@cs.berkeley.edu>
Tue, 3 Nov 2015 16:05:49 +0000 (11:05 -0500)
Counts the number of times we do a vmexit and stores that in proc under Qvmstatus

Signed-off-by: GanShun <ganshun@gmail.com>
[moved vmexits into struct vmm]
Signed-off-by: Barret Rhoden <brho@cs.berkeley.edu>
kern/arch/x86/vmm/intel/vmx.c
kern/arch/x86/vmm/vmm.h
kern/drivers/dev/proc.c
kern/include/ros/vmx.h
tests/vmm/vmrunkernel.c

index 440cf53..cbca000 100644 (file)
@@ -1857,6 +1857,10 @@ int vmx_launch(struct vmctl *v) {
                vmcs_writel(EOI_EXIT_BITMAP3_HIGH, 0);
 
                printk("v->apic %p v->pir %p\n", (void *)v->vapic, (void *)v->pir);
+               
+               // Initialize vmexits counter
+               for (int i = 0; i < 65; i++)
+                       current_proc->vmm.vmexits[i] = 0;
                // fallthrough
        case REG_RIP:
                printd("REG_RIP %p\n", v->regs.tf_rip);
@@ -1907,6 +1911,9 @@ int vmx_launch(struct vmctl *v) {
                
                //dumpmsrs();
                enable_irq();
+
+               current_proc->vmm.vmexits[ret] += 1;
+
                v->intrinfo1 = vmcs_readl(GUEST_INTERRUPTIBILITY_INFO);
                v->intrinfo2 = vmcs_readl(VM_EXIT_INTR_INFO);
                vmx_put_cpu(vcpu);
index 2325e38..93e35b7 100644 (file)
@@ -39,6 +39,7 @@ struct vmm {
                void *svm;
                struct vmx_vcpu **guest_pcores;
        };
+       unsigned long vmexits[65];      /* TODO: use a #define from a header */
 };
 
 void vmm_init(void);
index 319904f..fb33428 100644 (file)
@@ -30,6 +30,7 @@
 #include <pmap.h>
 #include <smp.h>
 #include <arch/vmm/vmm.h>
+#include <ros/vmx.h>
 
 struct dev procdevtab;
 
@@ -56,6 +57,7 @@ enum {
        Qregs,
        Qsegment,
        Qstatus,
+       Qvmstatus,
        Qtext,
        Qwait,
        Qprofile,
@@ -114,6 +116,7 @@ struct dirtab procdir[] = {
        //  {"regs",        {Qregs},    sizeof(Ureg),       0000},
        {"segment", {Qsegment}, 0, 0444},
        {"status", {Qstatus}, STATSIZE, 0444},
+       {"vmstatus", {Qvmstatus}, 0, 0444},
        {"text", {Qtext}, 0, 0000},
        {"wait", {Qwait}, 0, 0400},
        {"profile", {Qprofile}, 0, 0400},
@@ -527,6 +530,7 @@ static struct chan *procopen(struct chan *c, int omode)
                        c->aux = kzmalloc(sizeof(struct mntwalk), KMALLOC_WAIT);
                        break;
                case Qstatus:
+               case Qvmstatus:
                case Qctl:
                        break;
                case Qnotepg:
@@ -1136,6 +1140,24 @@ regread:
                                return readstr(off, va, n, buf);
                        }
 
+               case Qvmstatus:
+                       {
+                               char buf[50*65 + 2];
+                               int i, offset;
+                               offset=0;
+                               offset += snprintf(buf+offset, sizeof(buf)-offset, "{\n");
+                               for (i = 0; i < 65; i++) {
+                                       if (p->vmm.vmexits[i] != 0) {
+                                               offset += snprintf(buf+offset, sizeof(buf)-offset,
+                                                                  "\"%s\":\"%lld\",\n",
+                                                                  VMX_EXIT_REASON_NAMES[i],
+                                                                  p->vmm.vmexits[i]);
+                                       }
+                               }
+                               offset += snprintf(buf+offset, sizeof(buf)-offset, "}\n");
+                               kref_put(&p->p_kref);
+                               return readstr(off, va, n, buf);
+                       }
                case Qns:
                        //qlock(&p->debug);
                        if (waserror()) {
index f7cd365..b396a5c 100644 (file)
@@ -289,17 +289,22 @@ enum vmcs_field {
 #define EXIT_REASON_EXCEPTION_NMI       0
 #define EXIT_REASON_EXTERNAL_INTERRUPT  1
 #define EXIT_REASON_TRIPLE_FAULT        2
-
+#define EXIT_REASON_INIT_SIGNAL         3
+#define EXIT_REASON_START_UP_IPI        4
+#define EXIT_REASON_IO_SM_INTERRUPT     5
+#define EXIT_REASON_OTHER_SMI           6
 #define EXIT_REASON_PENDING_INTERRUPT   7
 #define EXIT_REASON_INTERRUPT_WINDOW    7
 #define EXIT_REASON_NMI_WINDOW          8
 #define EXIT_REASON_TASK_SWITCH         9
 #define EXIT_REASON_CPUID               10
+#define EXIT_REASON_GETSEC              11
 #define EXIT_REASON_HLT                 12
 #define EXIT_REASON_INVD                13
 #define EXIT_REASON_INVLPG              14
 #define EXIT_REASON_RDPMC               15
 #define EXIT_REASON_RDTSC               16
+#define EXIT_REASON_RSM                 17
 #define EXIT_REASON_VMCALL              18
 #define EXIT_REASON_VMCLEAR             19
 #define EXIT_REASON_VMLAUNCH            20
@@ -316,18 +321,32 @@ enum vmcs_field {
 #define EXIT_REASON_MSR_READ            31
 #define EXIT_REASON_MSR_WRITE           32
 #define EXIT_REASON_INVALID_STATE       33
+#define EXIT_REASON_ENTRY_MSR_LOADING   34
 #define EXIT_REASON_MWAIT_INSTRUCTION   36
+#define EXIT_REASON_MONITOR_TRAP_FLAG   37
 #define EXIT_REASON_MONITOR_INSTRUCTION 39
 #define EXIT_REASON_PAUSE_INSTRUCTION   40
 #define EXIT_REASON_MCE_DURING_VMENTRY  41
 #define EXIT_REASON_TPR_BELOW_THRESHOLD 43
 #define EXIT_REASON_APIC_ACCESS         44
+#define EXIT_REASON_VIRTUALIZED_EOI     45
+#define EXIT_REASON_GDTR_IDTR_ACCESS    46
+#define EXIT_REASON_LDTR_TR_ACCESS      47
 #define EXIT_REASON_EPT_VIOLATION       48
 #define EXIT_REASON_EPT_MISCONFIG       49
+#define EXIT_REASON_INVEPT              50
+#define EXIT_REASON_RDTSCP              51
+#define EXIT_REASON_VMX_TIMER_EXPIRED   52
+#define EXIT_REASON_INVVPID             53
 #define EXIT_REASON_WBINVD              54
 #define EXIT_REASON_XSETBV              55
-#define EXIT_REASON_APIC_WRITE         56
+#define EXIT_REASON_APIC_WRITE          56
+#define EXIT_REASON_RDRAND              57
 #define EXIT_REASON_INVPCID             58
+#define EXIT_REASON_VMFUNC              59
+#define EXIT_REASON_RDSEED              61
+#define EXIT_REASON_XSAVES              63
+#define EXIT_REASON_XRSTORS             64
 
 #define VMX_EXIT_REASONS \
        { EXIT_REASON_EXCEPTION_NMI,         "EXCEPTION_NMI" }, \
@@ -691,4 +710,20 @@ struct vmx_vcpu {
        struct vmcs *vmcs;
 };
 
+
+static char * const VMX_EXIT_REASON_NAMES[] = {
+       "EXCEPTION_NMI", "EXTERNAL_INTERRUPT", "TRIPLE_FAULT",
+       "INIT_SIGNAL", "START_UP_IPI", "IO_SM_INTERRUPT", "OTHER_SMI",
+       "INTERRUPT_WINDOW", "NMI_WINDOW", "TASK_SWITCH", "CPUID", "GETSEC", "HLT", "INVD",
+       "INVLPG", "RDPMC", "RDTSC", "RSM", "VMCALL", "VMCLEAR", "VMLAUNCH", "VMPTRLD",
+       "VMPTRST", "VMREAD", "VMRESUME", "VMWRITE", "VMOFF", "VMON", "CR_ACCESS",
+       "DR_ACCESS", "IO_INSTRUCTION", "MSR_READ", "MSR_WRITE", "INVALID_STATE", 
+       "ENTRY_MSR_LOADING", "35", "MWAIT_INSTRUCTION", "MONITOR_TRAP_FLAG", "38",
+       "MONITOR_INSTRUCTION", "PAUSE_INSTRUCTION", "MCE_DURING_VMENTRY", "42",
+       "TPR_BELOW_THRESHOLD", "APIC_ACCESS", "VIRTUALIZED_EOI", "GDTR_IDTR_ACCESS",
+       "LDTR_TR_ACCESS", "EPT_VIOLATION", "EPT_MISCONFIG", "INVEPT", "RDTSCP",
+       "VMX_TIMER_EXPIRED", "INVVPID", "WBINVD", "XSETBV", "APIC_WRITE", "RDRAND",
+       "INVPCID", "VMFUNC", "60", "RDSEED", "62", "XSAVES", "XRSTORS"
+};
+
 #endif /* ROS_INC_VMX_H */
index 102cf77..aa64943 100644 (file)
@@ -205,7 +205,7 @@ void *consout(void *arg)
                        for (j = 0; j < iov[i].length; j++)
                                printf("%c", ((char *)iov[i].v)[j]);
                }
-               
+               fflush(stdout);
                if (debug)
                        fprintf(stderr, "CCC: outlen is %d; inlen is %d\n", outlen, inlen);
                /* host: fill in the writeable buffers. */
@@ -742,7 +742,7 @@ fprintf(stderr, "%p %p %p %p\n", PGSIZE, PGSHIFT, PML1_SHIFT, PML1_PTE_REACH);
                        case EXIT_REASON_EXTERNAL_INTERRUPT:
                                //debug = 1;
                                if (debug) fprintf(stderr, "XINT 0x%x 0x%x\n", vmctl.intrinfo1, vmctl.intrinfo2);
-                               pir_dump();
+                               if (debug) pir_dump();
                                vmctl.command = RESUME;
                                break;
                        case EXIT_REASON_IO_INSTRUCTION: