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.


Ported user space support for host devices, user space host device example, and vnc...
Peter Dinda [Thu, 5 May 2011 18:14:38 +0000 (13:14 -0500)]
Note: the addition of x0vncserver as a binary is by intent.   Crufty to add as source right now

linux_usr/Makefile
linux_usr/v3_user_host_dev.c [new file with mode: 0644]
linux_usr/v3_user_host_dev.h [new file with mode: 0644]
linux_usr/v3_user_host_dev_example.c [new file with mode: 0644]
linux_usr/x0vncserver [new file with mode: 0755]

index 2fc1ad8..c2a23aa 100644 (file)
@@ -1,4 +1,5 @@
-all: v3_ctrl v3_stop v3_cons v3_mem v3_monitor v3_serial v3_net
+all: v3_ctrl v3_stop v3_cons v3_mem v3_monitor v3_serial v3_net v3_user_host_dev_example
+
 
 
 v3_ctrl : v3_ctrl.c v3_ctrl.h
@@ -23,5 +24,8 @@ v3_monitor : v3_cons.c v3_ctrl.h
 v3_net : v3_net.c v3_ctrl.h
        gcc -static v3_net.c -o v3_net
 
+v3_user_host_dev_example: v3_user_host_dev_example.c v3_user_host_dev.h v3_user_host_dev.c
+       gcc -static -I../linux_module v3_user_host_dev_example.c v3_user_host_dev.c -o v3_user_host_dev_example
+
 clean:
        rm -f v3_ctrl v3_cons v3_mem v3_monitor v3_serial v3_net
diff --git a/linux_usr/v3_user_host_dev.c b/linux_usr/v3_user_host_dev.c
new file mode 100644 (file)
index 0000000..8fe121a
--- /dev/null
@@ -0,0 +1,123 @@
+#include <unistd.h>
+#include <sys/stat.h>
+#include <fcntl.h>
+#include <malloc.h>
+
+#include "v3_user_host_dev.h"
+
+
+int v3_user_host_dev_rendezvous(char *vmdev, char *url)
+{
+    int vmfd;
+    int devfd;
+
+    if ((vmfd=open(vmdev,O_RDWR))<0) { 
+       return -1;
+    }
+
+    devfd = ioctl(vmfd,V3_VM_HOST_DEV_CONNECT,url);
+    
+    close(vmfd);
+
+    return devfd;
+
+}
+int v3_user_host_dev_depart(int devfd)
+{
+    return close(devfd);
+}
+
+
+int v3_user_host_dev_have_request(int devfd)
+{
+    uint64_t len;
+
+    return ioctl(devfd,V3_HOST_DEV_HOST_REQUEST_SIZE_IOCTL,&len)==1;
+}
+
+int v3_user_host_dev_pull_request(int devfd, struct palacios_host_dev_host_request_response **req)
+{
+    uint64_t len;
+    int rc;
+
+    rc=ioctl(devfd,V3_HOST_DEV_HOST_REQUEST_SIZE_IOCTL,&len);
+
+    if (rc<=0) { 
+       return -1;
+    } else {
+       struct palacios_host_dev_host_request_response *r = malloc(len);
+       
+       rc=ioctl(devfd, V3_HOST_DEV_HOST_REQUEST_PULL_IOCTL,r);
+       
+       if (rc<=0) { 
+           free(r);
+           return -1;
+       } else {
+           *req=r;
+           return 0;
+       }
+    }
+}
+               
+
+int v3_user_host_dev_push_response(int devfd, struct palacios_host_dev_host_request_response *resp)
+{
+    int rc;
+
+    rc=ioctl(devfd, V3_HOST_DEV_USER_RESPONSE_PUSH_IOCTL,resp);
+       
+    if (rc<=0) { 
+       return -1;
+    } else {
+       return 0;
+    }
+}
+               
+
+
+static uint64_t do_user(int devfd, struct palacios_host_dev_user_op *op)
+{
+    return ioctl(devfd, V3_HOST_DEV_USER_REQUEST_PUSH_IOCTL,op);
+}
+
+uint64_t v3_user_host_dev_read_guest_mem(int devfd, void *gpa, void *dest, uint64_t len)
+{
+    struct palacios_host_dev_user_op op;
+
+    op.type= PALACIOS_HOST_DEV_USER_REQUEST_READ_GUEST;
+    op.gpa=gpa;
+    op.data=dest;
+    op.len=len;
+    op.irq=0;
+    
+    return do_user(devfd,&op);
+}
+
+uint64_t v3_user_host_dev_write_guest_mem(int devfd, void *gpa, void *src, uint64_t len)
+{
+    struct palacios_host_dev_user_op op;
+
+    op.type= PALACIOS_HOST_DEV_USER_REQUEST_WRITE_GUEST;
+    op.gpa=gpa;
+    op.data=src;
+    op.len=len;
+    op.irq=0;
+    
+    return do_user(devfd,&op);
+}
+
+int      v3_user_host_dev_inject_irq(int devfd, uint8_t irq)
+{
+    struct palacios_host_dev_user_op op;
+
+    op.type= PALACIOS_HOST_DEV_USER_REQUEST_IRQ_GUEST;
+    op.gpa=0;
+    op.data=0;
+    op.len=0;
+    op.irq=irq;
+    
+    return do_user(devfd,&op);
+}
+
+
+
diff --git a/linux_usr/v3_user_host_dev.h b/linux_usr/v3_user_host_dev.h
new file mode 100644 (file)
index 0000000..523150f
--- /dev/null
@@ -0,0 +1,19 @@
+#ifndef _V3_USER_HOST_DEV_
+#define _V3_USER_HOST_DEV_
+
+#include <stdint.h>
+#include "palacios-host-dev-user.h"
+
+int v3_user_host_dev_rendezvous(char *vmdev, char *url); // returns devfd for use in poll/select
+int v3_user_host_dev_depart(int devfd);
+
+int v3_user_host_dev_have_request(int devfd);
+int v3_user_host_dev_pull_request(int devfd, struct palacios_host_dev_host_request_response **req);
+int v3_user_host_dev_push_response(int devfd, struct palacios_host_dev_host_request_response *resp);
+
+uint64_t v3_user_host_dev_read_guest_mem(int devfd, void *gpa, void *dest, uint64_t len);
+uint64_t v3_user_host_dev_write_guest_mem(int devfd, void *gpa, void *src, uint64_t len);
+int      v3_user_host_dev_inject_guest_irq(int devfd, uint8_t irq);
+
+#endif
+
diff --git a/linux_usr/v3_user_host_dev_example.c b/linux_usr/v3_user_host_dev_example.c
new file mode 100644 (file)
index 0000000..833f3c5
--- /dev/null
@@ -0,0 +1,124 @@
+#include <unistd.h>
+#include <stdlib.h>
+#include <stdio.h>
+#include <stdint.h>
+#include <string.h>
+#include <sys/select.h>
+#include <malloc.h>
+
+#include "v3_user_host_dev.h"
+
+void usage()
+{
+    fprintf(stderr,"v3_host_dev_example /dev/v3-vm0 user:mydev busywait|select\n");
+}
+
+
+int do_work(struct palacios_host_dev_host_request_response *req, 
+           struct palacios_host_dev_host_request_response **resp)
+{
+    uint64_t datasize;
+    
+    //
+    //
+    // Process request here, perhaps calling these functions:
+    //
+    // uint64_t v3_user_host_dev_read_guest_mem(int devfd, void *gpa, void *dest, uint64_t len);
+    // uint64_t v3_user_host_dev_write_guest_mem(int devfd, void *gpa, void *src, uint64_t len);
+    // int      v3_user_host_dev_inject_guest_irq(int devfd, uint8_t irq);
+    //
+    // determine datasize - # bytes to include in response
+    //
+    // now built a response
+    *resp = malloc(sizeof(struct palacios_host_dev_host_request_response) + datasize);
+    (*resp)->data_len = sizeof(struct palacios_host_dev_host_request_response) + datasize;
+
+    //
+    // Fill out the fields of the response - notice that there are six kinds of things to response to:
+    //   - read/write device port
+    //   - read/write device mem
+    //   - read/write device configuration space
+
+    return 0;
+}
+
+int main(int argc, char *argv[])
+{
+    int devfd;
+    int mode=0;
+    char *vm, *url;
+
+    if (argc!=4) { 
+       usage();
+       exit(-1);
+    }
+    
+    vm=argv[1];
+    url=argv[2];
+    mode = argv[3][0]=='s';
+
+    fprintf(stderr,"Attempting to rendezvous with host device %s on vm %s\n", url, vm);
+    
+    if ((devfd = v3_user_host_dev_rendezvous(vm,url))<0) { 
+       perror("failed to rendezvous");
+       exit(-1);
+    }
+    
+    fprintf(stderr,"Rendezvous succeeded, I will now operate in %s mode\n", mode==0 ? "busywait" : "select");
+    
+    if (mode==0) { 
+       //busywait
+
+       struct palacios_host_dev_host_request_response *req;
+       struct palacios_host_dev_host_request_response *resp;
+       uint64_t datasize;
+
+       while (1) { 
+           while (!(v3_user_host_dev_have_request(devfd))) { 
+           }
+           v3_user_host_dev_pull_request(devfd, &req);
+
+           do_work(req, &resp);
+           
+           v3_user_host_dev_push_response(devfd, resp);
+
+           free(resp);
+           free(req);
+       }
+    } else {
+
+       struct palacios_host_dev_host_request_response *req;
+       struct palacios_host_dev_host_request_response *resp;
+       uint64_t datasize;
+       fd_set   readset;
+       int rc;
+
+       // select-based operation so that you can wait for multiple things
+       
+       while (1) { 
+           FD_ZERO(&readset);
+           FD_SET(devfd,&readset);
+
+           rc = select(devfd+1, &readset, 0, 0, 0);  // pick whatever you want to select on, just include devfd
+
+           if (rc>0) { 
+               if (FD_ISSET(devfd,&readset)) { 
+                   // a request is read for us!
+                   v3_user_host_dev_pull_request(devfd, &req);
+
+                   do_work(req, &resp);
+                   
+                   v3_user_host_dev_push_response(devfd, resp);
+                   
+                   free(resp);
+                   free(req);
+               }
+           }
+       }
+    }
+
+    v3_user_host_dev_depart(devfd);
+
+    return 0;
+                   
+}
diff --git a/linux_usr/x0vncserver b/linux_usr/x0vncserver
new file mode 100755 (executable)
index 0000000..d173fe8
Binary files /dev/null and b/linux_usr/x0vncserver differ