From: Peter Dinda Date: Tue, 17 May 2011 00:10:33 +0000 (-0500) Subject: Updated kernel module and user tools to reflect ioctl changes for host devices X-Git-Url: http://v3vee.org/palacios/gitweb/gitweb.cgi?a=commitdiff_plain;h=4fdb3bc363a277d32fd95f58358470874b992c53;p=palacios.git Updated kernel module and user tools to reflect ioctl changes for host devices --- diff --git a/linux_module/palacios-host-dev-user.h b/linux_module/palacios-host-dev-user.h index 54b2e17..4f1334f 100644 --- a/linux_module/palacios-host-dev-user.h +++ b/linux_module/palacios-host-dev-user.h @@ -7,32 +7,32 @@ */ -#define V3_VM_HOST_DEV_CONNECT 512+1 +#define V3_VM_HOST_DEV_CONNECT (10244+1) /* to detemine whether a host request is available, poll the fd for read */ /* make a request for reading/writing guest or injecting irq */ /* the arguemnt is a pointer to a palacios_host_dev_user_op struct */ /* return is negative on error, positive to indicate bytes read/written or irq injected*/ -#define V3_HOST_DEV_USER_REQUEST_PUSH_IOCTL 1 +#define V3_HOST_DEV_USER_REQUEST_PUSH_IOCTL (10244+2) /* find out the size of the current host request, if one is pending */ /* you find out if one is pending by read poll/select on the fd */ /* the argument is a pointer to a uint64_t that will give the total size */ /* ioctl returns 1 if a request is ready, 0 if there is no request */ /* -EFAULT if there is a an error */ -#define V3_HOST_DEV_HOST_REQUEST_SIZE_IOCTL 2 +#define V3_HOST_DEV_HOST_REQUEST_SIZE_IOCTL (10244+3) /* get the current host request, if one is available */ /* the argument is a pointer to a palacios_host_dev_host_request_response */ /* of the needed size */ /* ioctl returns 1 if a request is ready+copied, 0 if there is no request */ /* -EFAULT if there is a an error */ -#define V3_HOST_DEV_HOST_REQUEST_PULL_IOCTL 3 +#define V3_HOST_DEV_HOST_REQUEST_PULL_IOCTL (10244+4) /* write back the response to the previously pulled host request */ /* the argument is a pointer to a palacios_host_dev_host_request_response */ -#define V3_HOST_DEV_USER_RESPONSE_PUSH_IOCTL 4 +#define V3_HOST_DEV_USER_RESPONSE_PUSH_IOCTL (10244+5) #ifdef __KERNEL__ diff --git a/linux_module/palacios-host-dev.c b/linux_module/palacios-host-dev.c index 686c962..c20e0fa 100644 --- a/linux_module/palacios-host-dev.c +++ b/linux_module/palacios-host-dev.c @@ -266,12 +266,14 @@ static int host_dev_release(struct inode * i, struct file * filp) return 0; } + static int host_dev_ioctl(struct inode *ip, struct file *fp, unsigned int val, unsigned long arg) { void __user *argp = (void __user *)arg; struct palacios_host_device_user *dev = fp->private_data; + if (!dev->connected) { return -EFAULT; } @@ -381,7 +383,7 @@ static int host_dev_ioctl(struct inode *ip, struct file *fp, unsigned int val, u } spin_unlock_irqrestore(&(dev->lock),f); - + return 1; // have request for you } @@ -462,6 +464,8 @@ static int host_dev_ioctl(struct inode *ip, struct file *fp, unsigned int val, u } + + static struct file_operations host_dev_fops = { .poll = host_dev_poll, .release = host_dev_release, @@ -846,7 +850,7 @@ static uint64_t palacios_host_dev_write_io(v3_host_dev_t hostdev, spin_unlock_irqrestore(&(dev->lock),f); return 0; } - + // resize request and response in case they will need it palacios_resize_reqresp(&(dev->req),len,0); // make room for data diff --git a/linux_module/palacios.h b/linux_module/palacios.h index b161832..76b4779 100644 --- a/linux_module/palacios.h +++ b/linux_module/palacios.h @@ -29,10 +29,10 @@ #define V3_VM_STREAM_CONNECT 21 #define V3_VM_STOP 22 -#define V3_VM_FB_INPUT 256+1 -#define V3_VM_FB_QUERY 256+2 +#define V3_VM_FB_INPUT (256+1) +#define V3_VM_FB_QUERY (256+2) -#define V3_VM_HOST_DEV_CONNECT 512+1 +#define V3_VM_HOST_DEV_CONNECT (10244+1) struct v3_guest_img { diff --git a/linux_usr/Makefile b/linux_usr/Makefile index c2a23aa..439494c 100644 --- a/linux_usr/Makefile +++ b/linux_usr/Makefile @@ -1,4 +1,4 @@ -all: v3_ctrl v3_stop v3_cons v3_mem v3_monitor v3_serial v3_net v3_user_host_dev_example +all: v3_ctrl v3_stop v3_cons v3_mem v3_monitor v3_serial v3_net v3_user_host_dev_example v3_os_debug @@ -27,5 +27,9 @@ v3_net : v3_net.c v3_ctrl.h 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 +v3_os_debug: v3_os_debug.c v3_user_host_dev.h v3_user_host_dev.c + gcc -static -I../linux_module v3_os_debug.c v3_user_host_dev.c -o v3_os_debug + + clean: - rm -f v3_ctrl v3_cons v3_mem v3_monitor v3_serial v3_net + rm -f v3_ctrl v3_cons v3_mem v3_monitor v3_serial v3_net v3_user_host_dev_example v3_os_debug diff --git a/linux_usr/v3_os_debug.c b/linux_usr/v3_os_debug.c new file mode 100644 index 0000000..c530964 --- /dev/null +++ b/linux_usr/v3_os_debug.c @@ -0,0 +1,128 @@ +#include +#include +#include +#include +#include +#include +#include + +#include "v3_user_host_dev.h" + +void usage() +{ + fprintf(stderr,"v3_user_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; + + switch (req->type) { + case PALACIOS_HOST_DEV_HOST_REQUEST_WRITE_IO: { + if (req->port==0xc0c0) { + uint64_t i; + uint64_t numchars; + numchars = req->data_len - sizeof(struct palacios_host_dev_host_request_response); + for (i=0;idata[i]); + } + *resp = malloc(sizeof(struct palacios_host_dev_host_request_response)); + **resp=*req; + (*resp)->len = (*resp)->data_len = sizeof(struct palacios_host_dev_host_request_response); + (*resp)->op_len = numchars; + } else { + printf("Huh? Unknown port %d\n",req->port); + } + } + break; + + default: + printf("Huh? Unknown request %d\n", req->type); + } + + + 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/v3_user_host_dev.c b/linux_usr/v3_user_host_dev.c index 8fe121a..709db76 100644 --- a/linux_usr/v3_user_host_dev.c +++ b/linux_usr/v3_user_host_dev.c @@ -2,6 +2,8 @@ #include #include #include +#include +#include #include "v3_user_host_dev.h" @@ -10,12 +12,17 @@ int v3_user_host_dev_rendezvous(char *vmdev, char *url) { int vmfd; int devfd; + char buf[256]; + + + strcpy(buf,url); + buf[255]=0; if ((vmfd=open(vmdev,O_RDWR))<0) { return -1; } - devfd = ioctl(vmfd,V3_VM_HOST_DEV_CONNECT,url); + devfd = ioctl(vmfd,V3_VM_HOST_DEV_CONNECT,buf); close(vmfd); @@ -32,7 +39,9 @@ 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 rc=ioctl(devfd,V3_HOST_DEV_HOST_REQUEST_SIZE_IOCTL,&len); + + return rc==1; } int v3_user_host_dev_pull_request(int devfd, struct palacios_host_dev_host_request_response **req)