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.


Linux kernel compatability enhancements (through 3.19)
Peter Dinda [Tue, 22 Dec 2015 00:43:11 +0000 (18:43 -0600)]
and other bug fixes

12 files changed:
linux_module/iface-file.c
linux_module/iface-keyed-stream.c
linux_module/iface-pstate-ctrl.c
linux_module/iface-pwrstat.c
linux_module/iface-pwrstat.h
linux_module/iface-socket.c
linux_module/main.c
linux_module/palacios-stubs.c
linux_module/palacios-vnet-brg.c
linux_module/palacios-vnet-ctrl.c
linux_module/palacios.h
palacios/src/gears/ext_syscall_hijack.c

index 6f69c3d..880c4d9 100644 (file)
@@ -21,7 +21,7 @@ static struct list_head global_files;
 #define isprint(a) ((a >= ' ') && (a <= '~'))
 
 #if LINUX_VERSION_CODE < KERNEL_VERSION(3,9,0)
-#define PAL_VFS_GETATTR(path, kstat) vfs_getattr(path.mnt, path.dentry, kstat)
+#define PAL_VFS_GETATTR(path, kstat) vfs_getattr((path)->mnt, (path)->dentry, kstat)
 #else
 #define PAL_VFS_GETATTR(path, kstat) vfs_getattr(path, kstat)
 #endif
@@ -282,7 +282,7 @@ static unsigned long long palacios_file_size(void * file_ptr) {
     struct kstat s;
     int ret;
     
-    ret = PAL_VFS_GETATTR(filp->f_path, &s);
+    ret = PAL_VFS_GETATTR(&(filp->f_path), &s);
 
     if (ret != 0) {
        ERROR("Failed to fstat file\n");
index 99524e1..1f75aa0 100644 (file)
@@ -657,12 +657,157 @@ struct file_stream {
     struct file *f;   // the opened file
 };
 
+/* lookup directory, see if it is writeable, and if so, create it if asked*/
+
+#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,41)
+
+static int lookup_check_mkdir(const char *path, int need_write, int create, unsigned short perms)
+{
+  struct nameidata nd;
+
+  if (path_lookup(path,LOOKUP_DIRECTORY|LOOKUP_FOLLOW,&nd)) { 
+    
+    // directory does does not exist.  
+    
+    if (!create) { 
+      // we are not being asked to create it
+      ERROR("attempt to open %s, which does not exist\n",path);
+      return -1;
+    } else {
+      // We are being asked to create it
+
+      struct dentry *de;
+      int err;
+      
+      // Find its parent
+      if (path_lookup(path,LOOKUP_PARENT|LOOKUP_FOLLOW,&nd)) { 
+       ERROR("attempt to create %s failed because its parent cannot be looked up\n",path);
+       return -1;
+      }
+      
+      // Can we write to the parent?
+      
+      if (inode_permission(nd.path.dentry->d_inode, MAY_WRITE | MAY_EXEC)) { 
+       ERROR("attempt to open %s, which has the wrong permissions for directory creation\n",path);
+       return -1;
+      }
+
+      // OK, we can, so let's create it
+      
+      de = lookup_create(&nd,1);
+      
+      if (!de || IS_ERR(de)) { 
+       ERROR("cannot allocate dentry\n");
+       return -1;
+      }
+
+      err = vfs_mkdir(nd.path.dentry->d_inode, de, perms);
+      
+      // lookup_create locks this for us!
+      
+      mutex_unlock(&(nd.path.dentry->d_inode->i_mutex));
+
+      if (err) {
+       ERROR("attempt to create %s failed because mkdir failed\n",path);
+       return -1;
+      }
+
+      // successfully created it. 
+      return 0;
+
+    }
+
+  } else {
+    
+    // it exists, can we read (and write, if needed) to it?
+    
+    if (inode_permission(nd.path.dentry->d_inode, MAY_EXEC | MAY_READ | need_write ? MAY_WRITE : 0 )) {
+      ERROR("attempt to open %s, which has the wrong permissions\n",path);
+      return -1;
+    }
+    
+    return 0;
+  }
+}
+#endif
+
+#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,41)
+static int lookup_check_mkdir(const char *path, int need_write, int create, unsigned short perms)
+{
+  struct path p; 
+
+  if (kern_path(path, LOOKUP_DIRECTORY|LOOKUP_FOLLOW, &p)) { 
+    
+    // directory does does not exist.  
+    
+    if (!create) { 
+      // we are not being asked to create it
+      ERROR("attempt to open %s, which does not exist\n",path);
+      return -1;
+    } else {
+      // We are being asked to create it
+
+      struct dentry *de;
+      int err;
+      
+      // Find its parent
+      if (kern_path(path,LOOKUP_PARENT|LOOKUP_FOLLOW,&p)) { 
+       ERROR("attempt to create %s failed because its parent cannot be looked up\n",path);
+       return -1;
+      }
+      
+      // Can we write to the parent?
+      
+      if (inode_permission(p.dentry->d_inode, MAY_WRITE | MAY_EXEC)) { 
+       ERROR("attempt to open %s, which has the wrong permissions for directory creation\n",path);
+       return -1;
+      }
+
+      // OK, we can, so let's create it
+      
+      de = kern_path_create(AT_FDCWD,path,&p,1);
+      
+      if (!de || IS_ERR(de)) { 
+       ERROR("cannot allocate dentry\n");
+       return -1;
+      }
+
+      err = vfs_mkdir(p.dentry->d_inode, de, perms);
+      
+      // lookup_create locks this for us!
+      
+      mutex_unlock(&(p.dentry->d_inode->i_mutex));
+
+      if (err) {
+       ERROR("attempt to create %s failed because mkdir failed\n",path);
+       return -1;
+      }
+
+      // successfully created it. 
+      return 0;
+
+    }
+    
+  } else {
+    
+    // it exists, can we read (and write, if needed) to it?
+    
+    if (inode_permission(p.dentry->d_inode, MAY_EXEC | MAY_READ | need_write ? MAY_WRITE : 0 )) {
+      ERROR("attempt to open %s, which has the wrong permissions\n",path);
+      return -1;
+    }
+    
+    return 0;
+  }
+}
+
+#endif
+
 
 static v3_keyed_stream_t open_stream_file(char *url,
                                          v3_keyed_stream_open_t ot)
 {
     struct file_keyed_stream *fks;
-    struct nameidata nd;
 
     if (strncasecmp(url,"file:",5)) { 
        WARNING("illegitimate attempt to open file stream \"%s\"\n",url);
@@ -690,74 +835,12 @@ static v3_keyed_stream_t open_stream_file(char *url,
 
     fks->ot= ot==V3_KS_WR_ONLY_CREATE ? V3_KS_WR_ONLY : ot;
 
-    // Does the directory exist, and can we read/write it?
-   
-    if (path_lookup(fks->path,LOOKUP_DIRECTORY|LOOKUP_FOLLOW,&nd)) { 
-
-       // directory does does not exist.  
-
-       if (ot==V3_KS_RD_ONLY || ot==V3_KS_WR_ONLY) { 
-
-           // we are not being asked to create it
-           ERROR("attempt to open %s, which does not exist\n",fks->path);
-           goto fail_out;
-
-       } else {
-
-           // We are being asked to create it
-
-           struct dentry *de;
-           int err;
-
-           // Find its parent
-           if (path_lookup(fks->path,LOOKUP_PARENT|LOOKUP_FOLLOW,&nd)) { 
-               ERROR("attempt to create %s failed because its parent cannot be looked up\n",fks->path);
-               goto fail_out;
-           }
-
-           // Can we write to the parent?
-
-           if (inode_permission(nd.path.dentry->d_inode, MAY_WRITE | MAY_EXEC)) { 
-               ERROR("attempt to open %s, which has the wrong permissions for directory creation\n",fks->path);
-               goto fail_out;
-           }
-
-           // OK, we can, so let's create it
-
-           de = lookup_create(&nd,1);
-
-           if (!de || IS_ERR(de)) { 
-               ERROR("cannot allocate dentry\n");
-               goto fail_out;
-           }
-
-           err = vfs_mkdir(nd.path.dentry->d_inode, de, 0700);
-
-           // lookup_create locks this for us!
-
-           mutex_unlock(&(nd.path.dentry->d_inode->i_mutex));
-
-           if (err) {
-               ERROR("attempt to create %s failed because mkdir failed\n",fks->path);
-               goto fail_out;
-           }
-
-           // now the directory should exist and have reasonable permissions
-           return (v3_keyed_stream_t) fks;
-       }
-    } 
-
-    
-    // we must be in V3_KS_RD_ONLY or V3_KS_WR_ONLY, 
-    // and the directory exists, so we must check the permissions
-
-    if (inode_permission(nd.path.dentry->d_inode, MAY_EXEC | (ot==V3_KS_RD_ONLY ? MAY_READ : MAY_WRITE))) {
-       ERROR("attempt to open %s, which has the wrong permissions\n",fks->path);
-       goto fail_out;
-    } else {
-       return (v3_keyed_stream_t) fks;
+    if (lookup_check_mkdir(fks->path,ot!=V3_KS_RD_ONLY,ot==V3_KS_WR_ONLY_CREATE,0700)) { 
+      ERROR("cannot find or create directory for stream\n");
+      goto fail_out;
     }
 
+    return fks;
 
  fail_out:
     palacios_free(fks->path);
@@ -2352,8 +2435,12 @@ static int send_msg(struct net_stream *ns,  char * buf, int len)
        msg.msg_namelen = 0;
        msg.msg_control = NULL;
        msg.msg_controllen = 0;
+#if LINUX_VERSION_CODE < KERNEL_VERSION(3,19,0)
        msg.msg_iov = &iov;
        msg.msg_iovlen = 1;
+#else
+       iov_iter_init(&(msg.msg_iter),WRITE,&iov,1,0);
+#endif
 
        iov.iov_base = (char *)&(buf[len-left]);
        iov.iov_len = (size_t)left;
@@ -2406,8 +2493,12 @@ static int recv_msg(struct net_stream *ns, char * buf, int len)
        msg.msg_namelen = 0;
        msg.msg_control = NULL;
        msg.msg_controllen = 0;
+#if LINUX_VERSION_CODE < KERNEL_VERSION(3,19,0)
        msg.msg_iov = &iov;
        msg.msg_iovlen = 1;
+#else
+       iov_iter_init(&(msg.msg_iter),READ,&iov,1,0);
+#endif
        
        iov.iov_base = (void *)&(buf[len-left]);
        iov.iov_len = (size_t)left;
index 9b3e4bb..2c49be9 100644 (file)
@@ -939,8 +939,22 @@ static int governor_switch(char * s, unsigned int cpu)
     argv[3] = NULL;
 
     /* KCH: we can't wait here to actually see if we succeeded, we're in interrupt context */
-    return call_usermodehelper_fns("/bin/sh", argv, envp, UMH_NO_WAIT, NULL, gov_switch_cleanup, NULL);
 
+#if LINUX_VERSION_CODE <= KERNEL_VERSION(3,9,0)
+    return call_usermodehelper_fns("/bin/sh", argv, envp, UMH_NO_WAIT, NULL, gov_switch_cleanup, NULL);
+#else
+    {
+      struct subprocess_info *sp;
+      
+      sp = call_usermodehelper_setup("/bin/sh", argv, envp, GFP_ATOMIC, NULL, gov_switch_cleanup, NULL);
+      if (!sp) { 
+       goto out_freeargv;
+      }
+      
+      return call_usermodehelper_exec(sp,0);
+    }
+#endif
+      
 out_freeargv:
     palacios_free(argv);
     return -1;
@@ -1740,27 +1754,22 @@ int pstate_proc_setup(void)
     struct proc_dir_entry *proc;
     struct proc_dir_entry *prochw;
 
-    proc = create_proc_entry("v3-dvfs",0444, palacios_get_procdir());
+    PAL_PROC_CREATE(proc,"v3-dvfs",0444,palacios_get_procdir(),&pstate_fops);
 
     if (!proc) { 
         ERROR("Failed to create proc entry for p-state control\n");
         return -1;
     }
 
-    proc->proc_fops = &pstate_fops;
-
     INFO("/proc/v3vee/v3-dvfs successfully created\n");
 
-    prochw = create_proc_entry("v3-dvfs-hw",0444,palacios_get_procdir());
-
+    PAL_PROC_CREATE(prochw,"v3-dvfs-hw",0444,palacios_get_procdir(),&pstate_hw_fops);
 
     if (!prochw) { 
         ERROR("Failed to create proc entry for p-state hw info\n");
         return -1;
     }
 
-    prochw->proc_fops = &pstate_hw_fops;
-
     INFO("/proc/v3vee/v3-dvfs-hw successfully created\n");
 
     return 0;
index 98ea8c0..8157fa2 100644 (file)
@@ -47,7 +47,7 @@ static struct rapl_domain rapl_domains[] = {
        [RAPL_DOMAIN_PKG] = {
                .domain_id = RAPL_DOMAIN_PKG,
                .msrs   = {
-                       .limit  = MSR_PKG_RAPL_POWER_LIMIT,
+                       .limit  = MSR_PKG_POWER_LIMIT,
                        .status = MSR_PKG_ENERGY_STATUS,
                },
                .valid  = 1,
index eb22df3..338140f 100644 (file)
@@ -9,9 +9,14 @@
 /* WARNING WARNING: this is speculation... */
 #define HASWELL_MODEL_NO 0x4A
 
-#define MSR_RAPL_POWER_UNIT            0x606
+#ifdef MSR_RAPL_POWER_UNIT
+// assume the rest are also defined by the kernel's msr include
+// except for special ones here
 
-#define MSR_PKG_RAPL_POWER_LIMIT       0x610
+#else
+// assume none are defined by the kernel's msr include
+#define MSR_RAPL_POWER_UNIT            0x606
+#define MSR_PKG_POWER_LIMIT            0x610
 #define MSR_PKG_ENERGY_STATUS          0x611
 #define MSR_PKG_PERF_STATUS            0x613
 #define MSR_PKG_POWER_INFO             0x614
@@ -33,6 +38,8 @@
 #define MSR_DRAM_PERF_STATUS           0x61B
 #define MSR_DRAM_POWER_INFO            0x61C
 
+#endif
+
 /* RAPL UNIT BITMASK */
 #define POWER_UNIT_OFFSET      0
 #define POWER_UNIT_MASK                0x0F
@@ -43,4 +50,5 @@
 #define TIME_UNIT_OFFSET       0x10
 #define TIME_UNIT_MASK         0xF0000
 
+
 #endif
index 7f0328c..3f85682 100644 (file)
@@ -301,8 +301,12 @@ palacios_send(
        msg.msg_namelen = 0;
        msg.msg_control = NULL;
        msg.msg_controllen = 0;
+#if LINUX_VERSION_CODE < KERNEL_VERSION(3,19,0)
        msg.msg_iov = &iov;
        msg.msg_iovlen = 1;
+#else
+       iov_iter_init(&(msg.msg_iter),WRITE,&iov,1,0);
+#endif
 
        iov.iov_base = (char *)buf;
        iov.iov_len = (size_t)len;
@@ -340,8 +344,12 @@ palacios_recv(
        msg.msg_namelen = 0;
        msg.msg_control = NULL;
        msg.msg_controllen = 0;
+#if LINUX_VERSION_CODE < KERNEL_VERSION(3,19,0)
        msg.msg_iov = &iov;
        msg.msg_iovlen = 1;
+#else
+       iov_iter_init(&(msg.msg_iter),READ,&iov,1,0);
+#endif
 
        iov.iov_base = (void *)&buf[0];
        iov.iov_len = (size_t)len;
@@ -385,8 +393,12 @@ palacios_sendto_ip(
        msg.msg_namelen = sizeof(struct sockaddr_in);
        msg.msg_control = NULL;
        msg.msg_controllen = 0;
+#if LINUX_VERSION_CODE < KERNEL_VERSION(3,19,0)
        msg.msg_iov = &iov;
        msg.msg_iovlen = 1;
+#else
+       iov_iter_init(&(msg.msg_iter),WRITE,&iov,1,0);
+#endif
 
        iov.iov_base = (char *)buf;
        iov.iov_len = (size_t)len;
@@ -433,8 +445,12 @@ palacios_recvfrom_ip(
        msg.msg_namelen = sizeof(struct sockaddr_in);
        msg.msg_control = NULL;
        msg.msg_controllen = 0;
+#if LINUX_VERSION_CODE < KERNEL_VERSION(3,19,0)
        msg.msg_iov = &iov;
        msg.msg_iovlen = 1;
+#else
+       iov_iter_init(&(msg.msg_iter),READ,&iov,1,0);
+#endif
 
        iov.iov_base = (void *)&buf[0];
        iov.iov_len = (size_t)len;
index 7b40e19..b0dbfee 100644 (file)
@@ -36,6 +36,7 @@
 
 #include "util-hashtable.h"
 
+
 MODULE_LICENSE("GPL");
 
 // Module parameter
index 7814987..039c170 100644 (file)
@@ -9,6 +9,11 @@
 #include <asm/irq_vectors.h>
 #include <asm/io.h>
 #include <asm/thread_info.h>
+#include <asm/i387.h>
+#include <linux/version.h>
+#if LINUX_VERSION_CODE >= KERNEL_VERSION(3,7,0)
+#include <asm/fpu-internal.h>
+#endif
 
 #include <linux/init.h>
 #include <linux/module.h>
@@ -420,6 +425,7 @@ static int lnx_thread_target(void * arg) {
     // We are a kernel thread that needs FPU save/restore state
     // vcores definitely need this, all the other threads get it too, 
     // but they just won't use it
+
     fpu_alloc(&(current->thread.fpu));
 #endif
 
index 945909a..abf4142 100644 (file)
@@ -162,7 +162,12 @@ static uint32_t _create_link(struct vnet_link * link) {
     if (link->sock_proto == UDP) { 
        // no UDP checksumming
        lock_sock(link->sock->sk);
+#if LINUX_VERSION_CODE < KERNEL_VERSION(3,16,0)
        link->sock->sk->sk_no_check = 1;
+#else
+       link->sock->sk->sk_no_check_tx = 1;
+       link->sock->sk->sk_no_check_rx = 1;
+#endif
        release_sock(link->sock->sk);
     }
 
@@ -258,8 +263,12 @@ _udp_send(struct socket * sock,
     msg.msg_namelen = sizeof(struct sockaddr_in);
     msg.msg_control = NULL;
     msg.msg_controllen = 0;
+#if LINUX_VERSION_CODE < KERNEL_VERSION(3,19,0)
     msg.msg_iov = &iov;
     msg.msg_iovlen = 1;
+#else
+    iov_iter_init(&(msg.msg_iter),WRITE,&iov,1,0);
+#endif
     msg.msg_control = NULL;
 
     oldfs = get_fs();
@@ -293,8 +302,12 @@ _udp_recv(struct socket * sock,
     msg.msg_namelen = sizeof(struct sockaddr_in);
     msg.msg_control = NULL;
     msg.msg_controllen = 0;
+#if LINUX_VERSION_CODE < KERNEL_VERSION(3,19,0)
     msg.msg_iov = &iov;
     msg.msg_iovlen = 1;
+#else
+    iov_iter_init(&(msg.msg_iter),READ,&iov,1,0);
+#endif
     msg.msg_control = NULL;
     
     oldfs = get_fs();
@@ -403,7 +416,12 @@ static int init_vnet_serv(void) {
     if (vnet_brg_s.serv_proto == UDP) { 
        // No UDP checksumming is done
        lock_sock(vnet_brg_s.serv_sock->sk);
+#if LINUX_VERSION_CODE < KERNEL_VERSION(3,16,0)
        vnet_brg_s.serv_sock->sk->sk_no_check = 1;
+#else
+       vnet_brg_s.serv_sock->sk->sk_no_check_tx = 1;
+       vnet_brg_s.serv_sock->sk->sk_no_check_rx = 1;
+#endif
        release_sock(vnet_brg_s.serv_sock->sk);
     }
 
index 86ec129..6dae6bb 100644 (file)
@@ -925,34 +925,33 @@ static int init_proc_files(void) {
        return -1;
     }
 
-    route_entry = create_proc_entry("routes", 0644, vnet_root);
+    
+    PAL_PROC_CREATE(route_entry,"routes",0644, vnet_root,&route_fops);
+
     if (route_entry == NULL) {
        remove_proc_entry("vnet", NULL);
        return -1;
     }
-    route_entry->proc_fops = &route_fops;
        
+    PAL_PROC_CREATE(link_entry,"links", 0644, vnet_root,&link_fops);
 
-    link_entry = create_proc_entry("links", 0644, vnet_root);
     if (link_entry == NULL) {
        remove_proc_entry("routes", vnet_root);
        remove_proc_entry("vnet", NULL);
        return -1;
     }
-    link_entry->proc_fops = &link_fops;
-       
 
-    stat_entry = create_proc_entry("stats", 0644, vnet_root);
+    PAL_PROC_CREATE(stat_entry,"stats", 0644, vnet_root, &stat_fops);
+
     if(stat_entry == NULL) {
        remove_proc_entry("links", vnet_root);
        remove_proc_entry("routes", vnet_root);
        remove_proc_entry("vnet", NULL);
        return -1;
     }
-    stat_entry->proc_fops = &stat_fops;
 
+    PAL_PROC_CREATE(debug_entry,"debug", 0644, vnet_root,&debug_fops);
 
-    debug_entry = create_proc_entry("debug", 0644, vnet_root);
     if(debug_entry == NULL) {
        remove_proc_entry("links", vnet_root);
        remove_proc_entry("routes", vnet_root);
@@ -960,7 +959,6 @@ static int init_proc_files(void) {
        remove_proc_entry("vnet", NULL);
        return -1;
     }
-    debug_entry->proc_fops = &debug_fops;
 
     vnet_ctrl_s.vnet_proc_root = vnet_root;
 
index 4694637..fc406bf 100644 (file)
@@ -260,6 +260,10 @@ void  palacios_mutex_unlock_irqrestore(void *mutex, void *flags);
 #endif
 
 
+#if LINUX_VERSION_CODE > KERNEL_VERSION(3,9,0)
+#define strict_strtoull(s,b,r) kstrtoull(s,b,r)
+#endif
+
 
 
 #endif
index 8e21769..c31bb59 100644 (file)
@@ -133,6 +133,7 @@ int v3_syscall_handler (struct guest_info * core, uint8_t vector, void * priv_da
         if (list_empty(&(injects->code_inject_list))) {
             return 0;
         } else {
+           int ret;
 
             inject = (struct v3_code_inject_info*) list_first_entry(
                         &(injects->code_inject_list),