Palacios Public Git Repository

To checkout Palacios execute

  git clone http://v3vee.org/palacios/palacios.web/palacios.git
This will give you the master branch. You probably want the devel branch or one of the release branches. To switch to the devel branch, simply execute
  cd palacios
  git checkout --track -b devel origin/devel
The other branches are similar.


HVM capability enhancement: asynchronous upcalls to ROS userspace
[palacios.git] / linux_usr / v3_ctrl.c
index c8bf216..54e8df7 100644 (file)
@@ -1,6 +1,7 @@
 /* 
- * V3 Control utility
+ * V3 Control Library
  * (c) Jack lange, 2010
+ *     Kyle Hale,  2012
  */
 
 
 #include <sys/ioctl.h> 
 #include <sys/stat.h> 
 #include <sys/types.h> 
+#include <sys/mman.h>
 #include <unistd.h> 
 #include <string.h>
  
 #include "v3_ctrl.h"
 
-int read_file(int fd, int size, unsigned char * buf);
 
-int main(int argc, char* argv[]) {
-    char * filename = argv[1];
-    char * name = argv[2];
-    int guest_fd = 0;
-    int v3_fd = 0;
-    struct v3_guest_img guest_img;
-    struct stat guest_stats;
-    memset(&guest_img, 0, sizeof(struct v3_guest_img));
+/*
+ * create a file-backed memory region 
+ */
+void * v3_mmap_file (const char * filename, int prot, int flags) {
+    int fd;
+    struct stat st;
+    void * m;
+
+    fd = open(filename, O_RDONLY);
+    if (!fd) {
+        fprintf(stderr, "Error opening file for mapping: %s\n", filename);
+        return NULL;
+    }
 
-    if (argc <= 2) {
-       printf("Usage: ./v3_ctrl <guest_img> <vm name>\n");
-       return -1;
+    fstat(fd, &st);
+
+    if ((m = mmap(NULL, st.st_size, prot, flags, fd, 0)) == MAP_FAILED) {
+        fprintf(stderr, "Error mapping file (%s)\n", filename);
+        close(fd);
+        return NULL;
     }
 
-    printf("Launching guest: %s\n", filename);
+    close(fd);
+    return m;
+}
 
-    guest_fd = open(filename, O_RDONLY); 
 
-    if (guest_fd == -1) {
-       printf("Error Opening guest image: %s\n", filename);
-       return -1;
+/*
+ * read a file into a buffer
+ */
+int v3_read_file (int fd, int size, unsigned char * buf) {
+    int left_to_read = size;
+    int have_read = 0;
+
+    while (left_to_read != 0) {
+       int bytes_read = read(fd, buf + have_read, left_to_read);
+
+       if (bytes_read <= 0) {
+           break;
+       }
+
+       have_read += bytes_read;
+       left_to_read -= bytes_read;
     }
 
-    if (fstat(guest_fd, &guest_stats) == -1) {
-       printf("ERROR: Could not stat guest image file -- %s\n", filename);
+    if (left_to_read != 0) {
+       fprintf(stderr, "Error could not finish reading file\n");
        return -1;
     }
-
     
-    guest_img.size = guest_stats.st_size;
-    
-    // load guest image into user memory
-    guest_img.guest_data = malloc(guest_img.size);
+    return 0;
+}
 
-    read_file(guest_fd, guest_img.size, guest_img.guest_data);
-    
-    close(guest_fd);
 
-    printf("Loaded guest image. Launching to V3Vee\n");
-    
-    strncpy(guest_img.name, name, 127);
+/*
+ * perform an ioctl on v3vee device
+ */
+int v3_dev_ioctl (int request, void * arg) {
+    int fd, ret;
 
+    fd = open(v3_dev, O_RDONLY);
+    if (fd == -1) {
+        fprintf(stderr, "Error opening V3Vee control device\n");
+        return -1;
+    }
 
-    v3_fd = open(v3_dev, O_RDONLY);
+    ret = ioctl(fd, request, arg);
 
-    if (v3_fd == -1) {
-       printf("Error opening V3Vee control device\n");
-       return -1;
+    if (ret < 0) 
+        fprintf(stderr, "IOCTL error on V3Vee control device (%d)\n", ret);
+
+
+    close(fd);
+    return ret;
+}
+
+
+/*
+ * perform an ioctl on arbitrary VM device
+ */
+int v3_vm_ioctl (const char * filename, 
+                 int request, 
+                 void * arg) { 
+    int fd, ret;
+
+    fd = open(filename, O_RDONLY);
+    if (fd == -1) {
+        fprintf(stderr, "Error opening V3Vee VM device: %s\n", filename);
+        return -1;
     }
 
-    ioctl(v3_fd, V3_START_GUEST, &guest_img); 
+    ret = ioctl(fd, request, arg);
 
+    if (ret < 0) 
+        fprintf(stderr, "IOCTL error on device %s (%d)\n", filename, ret);
 
+    close(fd);
+    return ret;
+}
 
-    /* Close the file descriptor.  */ 
-    close(v3_fd); 
 
+/* 
+ * launch a VM with VM device path
+ */
+int launch_vm (const char * filename) {
+    int err;
 
-    return 0; 
-} 
+    printf("Launching VM (%s)\n", filename);
+    err = v3_vm_ioctl(filename, V3_VM_LAUNCH, NULL);
 
+    if (err < 0) {
+        fprintf(stderr, "Error launching VM (%s)\n", filename);
+        return -1;
+    }
 
+    return 0;
+}
 
-int read_file(int fd, int size, unsigned char * buf) {
-    int left_to_read = size;
-    int have_read = 0;
 
-    while (left_to_read != 0) {
-       int bytes_read = read(fd, buf + have_read, left_to_read);
+/*
+ * stop a VM with VM device path
+ */
+int stop_vm (const char * filename) {
+    int err;
 
-       if (bytes_read <= 0) {
-           break;
-       }
+    printf("Stopping VM (%s)\n", filename);
 
-       have_read += bytes_read;
-       left_to_read -= bytes_read;
-    }
+    if (v3_vm_ioctl(filename, V3_VM_STOP, NULL) < 0) 
+        return -1;
 
-    if (left_to_read != 0) {
-       printf("Error could not finish reading file\n");
-       return -1;
-    }
-    
     return 0;
 }
+
+
+/*
+ * generic ELF header buffer hash function. 
+ * Mirrors internal Palacios implementation
+ */
+unsigned long v3_hash_buffer (unsigned char * msg, unsigned int len) {
+    unsigned long hash = 0;
+    unsigned long temp = 0;
+    unsigned int i;
+
+    for (i = 0; i < len; i++) {
+        hash = (hash << 4) + *(msg + i) + i;
+        if ((temp = (hash & 0xF0000000))) {
+            hash ^= (temp >> 24);
+        }
+        hash &= ~temp;
+    }
+    return hash;
+}
+