Enable "VMCALL console putc" via flags. (XCC)
authorRonald G. Minnich <rminnich@gmail.com>
Tue, 23 Jun 2015 18:04:52 +0000 (11:04 -0700)
committerBarret Rhoden <brho@cs.berkeley.edu>
Fri, 26 Jun 2015 18:41:30 +0000 (11:41 -0700)
We extend the vmm struct with flags.

The only flag now is VMM_VMCALL_PRINTF. If this is set, then the vmcall handler
will print out the lowest byte of the first argument to the console.

Reinstall your kernel headers.

Signed-off-by: Ronald G. Minnich <rminnich@gmail.com>
kern/arch/x86/vmm/intel/vmx.c
kern/arch/x86/vmm/vmm.c
kern/arch/x86/vmm/vmm.h
kern/include/ros/vmm.h [new file with mode: 0644]
kern/src/syscall.c
tests/vmm/vmrunkernel.c

index 148a485..308f1fe 100644 (file)
 
 #include "vmx.h"
 #include "../vmm.h"
+#include <ros/vmm.h>
 
 #include "cpufeature.h"
 
@@ -1409,20 +1410,19 @@ int vmx_launch(uint64_t rip, uint64_t rsp, uint64_t cr3)
                vmx_put_cpu(vcpu);
 
                if (ret == EXIT_REASON_VMCALL) {
-                       // hacque. vmcall is now putchar.
-                       if (0) {
-                               vcpu->shutdown = SHUTDOWN_UNHANDLED_EXIT_REASON;
-                               uint8_t byte = vcpu->regs.tf_rdi;
-                               printk("%p %c\n", byte, vcpu->regs.tf_rdi);
-                               vmx_dump_cpu(vcpu);
-                               printd("system call! WTF\n");
-                       } else {
+                       if (current->vmm.flags & VMM_VMCALL_PRINTF) {
                                uint8_t byte = vcpu->regs.tf_rdi;
                                printk("%c", byte);
                                // adjust the RIP
                                vmx_get_cpu(vcpu);
                                vmcs_writel(GUEST_RIP, vcpu->regs.tf_rip + 3);
                                vmx_put_cpu(vcpu);
+                       } else {
+                               vcpu->shutdown = SHUTDOWN_UNHANDLED_EXIT_REASON;
+                               uint8_t byte = vcpu->regs.tf_rdi;
+                               printk("%p %c\n", byte, vcpu->regs.tf_rdi);
+                               vmx_dump_cpu(vcpu);
+                               printd("system call! WTF\n");
                        }
                } else if (ret == EXIT_REASON_CPUID) {
                        vmx_handle_cpuid(vcpu);
index 53961be..25c31e9 100644 (file)
@@ -16,6 +16,7 @@
 
 #include "intel/vmx.h"
 #include "vmm.h"
+#include <ros/vmm.h>
 
 /* TODO: have better cpuid info storage and checks */
 bool x86_supports_vmx = FALSE;
@@ -69,10 +70,18 @@ int vm_run(uint64_t rip, uint64_t rsp, uint64_t cr3)
 
 /* Initializes a process to run virtual machine contexts, returning the number
  * initialized, optionally setting errno */
-int vmm_struct_init(struct proc *p, unsigned int nr_guest_pcores)
+int vmm_struct_init(struct proc *p, unsigned int nr_guest_pcores, int flags)
 {
        struct vmm *vmm = &p->vmm;
        unsigned int i;
+       if (flags & ~VMM_ALL_FLAGS) {
+               set_errstr("%s: flags is 0x%lx, VMM_ALL_FLAGS is 0x%lx\n", __func__,
+                          flags, VMM_ALL_FLAGS);
+               set_errno(EINVAL);
+               return 0;
+       }
+       vmm->flags = flags;
+
        if (!x86_supports_vmx) {
                set_errno(ENODEV);
                return 0;
index a124ec7..26a9060 100644 (file)
@@ -20,6 +20,8 @@ struct vmm {
        // true if this is a VMMCP.
        bool vmmcp;
 
+       int flags;
+
        // Number of cores in this VMMCP.
        int nr_guest_pcores;
 
@@ -40,7 +42,7 @@ struct vmm {
 void vmm_init(void);
 void vmm_pcpu_init(void);
 
-int vmm_struct_init(struct proc *p, unsigned int nr_guest_pcores);
+int vmm_struct_init(struct proc *p, unsigned int nr_guest_pcores, int flags);
 void __vmm_struct_cleanup(struct proc *p);
 
 int vm_run(uint64_t,uint64_t, uint64_t);
diff --git a/kern/include/ros/vmm.h b/kern/include/ros/vmm.h
new file mode 100644 (file)
index 0000000..309e9f8
--- /dev/null
@@ -0,0 +1,13 @@
+/* Copyright (c) 2015 Google Inc.
+ * Barret Rhoden <brho@cs.berkeley.edu>
+ * See LICENSE for details.
+ *
+ * 64 bit KPT helpers */
+
+#ifndef ROS_INC_VMM_H
+#define ROS_INC_VMM_H
+
+#define        VMM_VMCALL_PRINTF       0x1     /* Enable VMCALL output console hack */
+
+#define VMM_ALL_FLAGS  (VMM_VMCALL_PRINTF)
+#endif /* ROS_INC_VMM_H */
index d2c2e66..0f59d7e 100644 (file)
@@ -1170,9 +1170,10 @@ static int sys_change_to_m(struct proc *p)
 
 /* Initializes a process to run virtual machine contexts, returning the number
  * initialized, optionally setting errno */
-static int sys_setup_vmm(struct proc *p, unsigned int nr_guest_pcores)
+static int sys_setup_vmm(struct proc *p, unsigned int nr_guest_pcores,
+                         int flags)
 {
-       return vmm_struct_init(p, nr_guest_pcores);
+       return vmm_struct_init(p, nr_guest_pcores, flags);
 }
 
 /* Pokes the ksched for the given resource for target_pid.  If the target pid
index 0983a4f..461ce89 100644 (file)
@@ -13,6 +13,7 @@
 #include <ros/syscall.h>
 #include <sys/mman.h>
 #include <vmm/coreboot_tables.h>
+#include <ros/vmm.h>
 
 /* this test will run the "kernel" in the negative address space. We hope. */
 int *mmap_blob;
@@ -46,6 +47,7 @@ int nr_threads = 2;
 int main(int argc, char **argv)
 {
        int amt;
+       int vmmflags = VMM_VMCALL_PRINTF;
        uint64_t entry = 0x101000c, kerneladdress = 0x1010000;
        int nr_gpcs = 1;
        int fd = open("#c/sysctl", O_RDWR), ret;
@@ -66,6 +68,20 @@ int main(int argc, char **argv)
                exit(1);
        }
        argc--,argv++;
+       // switches ...
+       while (1) {
+               if (*argv[0] != '-')
+                       break;
+               switch(argv[0][1]) {
+               case 'n':
+                       vmmflags &= ~VMM_VMCALL_PRINTF;
+                       break;
+               default:
+                       printf("BMAFR\n");
+                       break;
+               }
+               argc--,argv++;
+       }
        if (argc < 1) {
                fprintf(stderr, "Usage: %s vmimage coreboot_tables [loadaddress [entrypoint]]\n", argv[0]);
                exit(1);
@@ -95,7 +111,8 @@ int main(int argc, char **argv)
        }
        fprintf(stderr, "Read in %d bytes\n", x-kerneladdress);
 
-       if (ros_syscall(SYS_setup_vmm, nr_gpcs, 0, 0, 0, 0, 0) != nr_gpcs) {
+       fprintf(stderr, "Run with %d cores and vmmflags 0x%x\n", nr_gpcs, vmmflags);
+       if (ros_syscall(SYS_setup_vmm, nr_gpcs, vmmflags, 0, 0, 0, 0) != nr_gpcs) {
                perror("Guest pcore setup failed");
                exit(1);
        }