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.


more extension ports
[palacios.git] / linux_module / palacios-host-dev.c
1 /* 
2  * Host device interface + user-space device interface
3  * (c) 2011 Peter Dinda
4  */
5
6 #include <linux/device.h>
7 #include <linux/cdev.h>
8 #include <linux/errno.h>
9 #include <linux/fs.h>
10 #include <linux/uaccess.h>
11 #include <linux/poll.h>
12 #include <linux/anon_inodes.h>
13 #include <linux/file.h>
14 #include <linux/sched.h>
15 #include <linux/delay.h>
16
17 #include <interfaces/vmm_host_dev.h>
18
19 #include "palacios.h"
20 #include "palacios-host-dev.h"
21 #include "palacios-host-dev-user.h"
22
23
24
25 /*
26   There are two things in this file:
27
28
29   1. An implementation of the Palacios host device interface that will
30      accept any URL from Palacios.  Currently, the only URL type it will
31      handle is user:<name>, but it should be clear how to extend with
32      other types.
33
34      Palacios opens a host device by issuing something like this:
35
36          palacios_host_dev_open( impl="user:foo" busclass=pci, opaque )
37
38      This will attempt to rendezvous with the user space device The
39      rendevzous retry and timeout periods can be set below.
40
41   2. An implementation of user: urls - the host interface is mapped
42      into an RPC-like interface to/from user space via a file
43      interface.   
44
45      The user space gets a file descriptor like this:
46
47      int vmfd = open("/dev/v3-vmX",...);
48
49      int devfd = ioctl(vmfd,V3_HOST_DEV_CONNECT,"user:foo"); 
50
51      This will attempt to rendezvous with the host side.
52
53      If it returns successfully, you can now issue synchronous,
54      blocking RPCs to the guest to read/write its memory and inject
55      irqs.  This means that a user->host request is handled
56      immediately, and independently of any host->user request. 
57
58      struct palacios_host_dev_user_op op;
59
60      // fill out op
61      op.type = PALACIOS_HOST_DEV_USER_REQUEST_WRITE_GUEST; 
62      ...
63
64      ioctl(devfd, V3_HOST_DEV_USER_REQUEST_PUSH_IOCTL, &op);
65
66      // return value is # bytes read or written; or 0 if irq injected
67      // negative value is error
68
69      The interface from the host to the user side is asynchronous
70      blocking RPC.  Any host device will have at most one outstanding
71      request from palacios.  The implementation here stores the
72      request until the user side is ready to accept it.  The user side
73      can check if there is a request via a poll/select or an ioctl.
74      The ioctl also returns the needed size for the request structure.
75      After the user side has a request, it is expected to process it,
76      perhaps making user->host requests as described above, and then
77      return a response.  Only one host->user request should be in
78      progress at any time in the user space.
79
80      What this looks like is:
81      
82      poll(...devfd for read...) or select(...devfd for read...)
83
84      if (devfd is marked readable) { 
85          uint64_t size;
86
87          ioctl(devfd,V3_HOST_DEV_HOST_REQUEST_SIZE_IOCTL,&size);
88          // returns 1 if there is a request, 0 if not, negative on err
89
90          struct palacios_host_dev_host_request_response *req;
91
92          req = allocate req to be at least size bytes long
93
94          ioctl(devfd,V3_HOST_DEV_HOST_REQUEST_PULL_IOCTL,req)
95          // returns 1 if there is a request, 0 if not, negative on err
96          
97          // process request, perhaps using above user->host request
98          // build response structure
99          // resp.data_len == size of structure including relevant data at end
100
101          ioctl(devfd,V3_HOST_DEV_USER_RESPONSE_PUSH_IOCTL,resp);
102          // returns 0 if there is no outstanding request (user error)
103          // 1 on success, negative on error
104      }
105     
106
107 */
108
109
110 #define MAX_URL 256
111
112 #define RENDEZVOUS_WAIT_SECS  60
113 #define RENDEZVOUS_RETRY_SECS 1
114
115 #define DEEP_DEBUG    0
116 #define SHALLOW_DEBUG 0
117
118 #if DEEP_DEBUG
119 #define DEEP_DEBUG_PRINT(fmt, args...) printk((fmt), ##args)
120 #else
121 #define DEEP_DEBUG_PRINT(fmt, args...) 
122 #endif
123
124 #if SHALLOW_DEBUG
125 #define SHALLOW_DEBUG_PRINT(fmt, args...) printk((fmt), ##args)
126 #else
127 #define SHALLOW_DEBUG_PRINT(fmt, args...) 
128 #endif
129
130
131 #define ERROR(fmt, args...) printk((fmt), ##args)
132 #define INFO(fmt, args...) printk((fmt), ##args)
133
134 struct palacios_host_device_user {
135     spinlock_t lock;
136     int      connected;    // is the user space connected to this?
137     int      waiting;      // am I waiting for a user-space response?
138
139     int      fd;           // what is the user space fd?
140
141     char     url[MAX_URL]; // what is the url describing the device
142
143     v3_guest_dev_t guestdev; // what is the palacios-side device
144
145     wait_queue_head_t  user_wait_queue; // user space processes waiting on us (should be only one)
146     wait_queue_head_t  host_wait_queue; // host threads (should only be one) waiting on user space
147
148     struct v3_guest                                *guest; // my guest
149     struct palacios_host_dev_host_request_response *req;   // curent request
150     struct palacios_host_dev_host_request_response *resp;  // curent response
151
152     struct list_head  node;   // for adding me to the list of hostdevs this VM has
153 };
154
155
156 /**************************************************************************************
157   Utility functions
158 *************************************************************************************/
159
160 static void palacios_host_dev_user_free(struct palacios_host_device_user *dev)
161 {
162     if (dev->req) {
163         kfree(dev->req);
164         dev->req=0;
165     } 
166     if (dev->resp) { 
167         kfree(dev->resp);
168         dev->resp=0;
169     }
170     kfree(dev);
171 }
172
173
174 //
175 // Is this structure big enough for the data_size we will use?
176 //
177 // THIS FUNCTION CAN BE CALLED WHILE INTERRUPTS ARE OFF
178 //
179 static int palacios_bigenough_reqresp(struct palacios_host_dev_host_request_response *r, uint64_t data_size)
180 {
181     if (!r) { 
182         return 0;
183     } else {
184         if (((r->len)-sizeof(struct palacios_host_dev_host_request_response)) < data_size) {
185             return 0;
186         } else {
187             return 1;
188         }
189     }
190 }
191
192 //
193 // Resize a request/response structure so that it will fit data_size bytes
194 //
195 // At the end of this, *r->len >= sizeof(struct)+data_size
196 //
197 // THIS FUNCTION MAY SLEEP AS IT CALLS KMALLOC 
198 // DO NOT CALL IT WHILE HOLDING A SPIN LOCK WITH INTERRUPTS OFF
199 //
200 static int palacios_resize_reqresp(struct palacios_host_dev_host_request_response **r, uint64_t data_size, int copy)
201 {
202     
203     DEEP_DEBUG_PRINT("palacios: hostdev: resize 0x%p to %llu\n",*r,data_size);
204
205     if ((*r)==0) { 
206         // allocate it
207         DEEP_DEBUG_PRINT("palacios: hostdev: attempt alloc\n");
208         *r = kmalloc(sizeof(struct palacios_host_dev_host_request_response)+data_size,GFP_KERNEL);
209         DEEP_DEBUG_PRINT("palacios: hostdev: kmalloc done\n");
210         if ((*r)==0) { 
211             ERROR("palacios: hostdev: failed to allocate\n");
212             return -1;
213         } else {
214             (*r)->len=sizeof(struct palacios_host_dev_host_request_response)+data_size;
215             DEEP_DEBUG_PRINT("palacios: hostdev: allocated\n");
216             return 0;
217         }
218     } else {
219         //let it go if it's big enough
220         uint64_t cur_len = (*r)->len-sizeof(struct palacios_host_dev_host_request_response);
221
222         if (data_size<=cur_len) { 
223             // do nothing
224             DEEP_DEBUG_PRINT("palacios: hostdev: size ok\n");
225             return 0;
226         } else {
227             struct palacios_host_dev_host_request_response *new;
228
229             if (!copy) { 
230                 kfree(*r);
231                 *r=0;
232             }
233             new = kmalloc(sizeof(struct palacios_host_dev_host_request_response)+data_size,GFP_KERNEL);
234             if (!new) { 
235                 ERROR("palacios: hostdev: failed to reallocate\n");
236                 return -1;
237             } else {
238                 new->len=sizeof(struct palacios_host_dev_host_request_response)+data_size;
239                 if (copy) { 
240                     memcpy(new->data,(*r)->data,(*r)->data_len-sizeof(struct palacios_host_dev_host_request_response));
241                     new->data_len=(*r)->data_len;
242                     kfree(*r);
243                 }
244                 *r=new;
245                 DEEP_DEBUG_PRINT("palacios: hostdev: reallocated\n");
246                 return 0;
247             }
248         }
249     }
250 }
251
252 static void cycle_request_response(struct palacios_host_device_user *dev)
253 {
254     DEEP_DEBUG_PRINT("palacios: hostdev: cycle request to response\n");
255     // wake up user side so that polls fall through
256     wake_up_interruptible(&(dev->user_wait_queue));
257     // put us to sleep until the user side wakes us up
258     while (wait_event_interruptible((dev->host_wait_queue), (dev->waiting==0)) != 0) {}
259
260     DEEP_DEBUG_PRINT("palacios: hostdev: cycle request to response - done\n");
261 }
262
263 static void cycle_response_request(struct palacios_host_device_user *dev)
264 {
265     DEEP_DEBUG_PRINT("palacios: hostdev: cycle response to request\n");
266     // wake up host side
267     wake_up_interruptible(&(dev->host_wait_queue));
268     DEEP_DEBUG_PRINT("palacios: hostdev: cycle response to request - done\n");
269 }
270
271     
272 /*********************************************************************************************
273
274     Interface to user space
275
276  *********************************************************************************************/ 
277
278
279
280 static unsigned int host_dev_poll(struct file * filp, 
281                                   struct poll_table_struct * poll_tb) 
282 {
283
284     struct palacios_host_device_user * dev = filp->private_data;
285     unsigned long f;
286
287     SHALLOW_DEBUG_PRINT("palacios: hostdev: poll\n");
288
289     if (!dev->connected) { 
290         ERROR("palcios: hostdev: poll on unconnected device\n");
291         return -EFAULT;
292     }
293
294     spin_lock_irqsave(&(dev->lock),f);
295
296     if (dev->waiting) { 
297         // Yes, we have a request if you want it!
298         spin_unlock_irqrestore(&(dev->lock),f);
299         DEEP_DEBUG_PRINT("palacios: hostdev: poll done immediate\n");
300         return  POLLIN | POLLRDNORM;
301     } 
302
303     // No request yet, so we need to wait for one to show up.
304
305     // register ourselves on the user wait queue
306     poll_wait(filp, &(dev->user_wait_queue), poll_tb);
307
308     spin_unlock_irqrestore(&(dev->lock),f);
309
310     DEEP_DEBUG_PRINT("palacios: hostdev: poll delayed\n");
311     // We will get called again when that queue is woken up
312
313     return 0;
314 }
315
316
317 static int host_dev_release(struct inode * i, struct file * filp) 
318 {
319     struct palacios_host_device_user *dev = filp->private_data;
320     unsigned long f;
321
322     INFO("palacios: user side is closing host device \"%s\"\n",dev->url);
323     
324     spin_lock_irqsave(&(dev->lock), f);
325     dev->connected = 0;
326     spin_unlock_irqrestore(&(dev->lock), f);
327
328     // it is the palacios->host interface's responsibility to ignore
329     // reads/writes until connected is true
330
331     return 0;
332 }
333
334
335 static int host_dev_ioctl(struct inode *ip, struct file *fp, unsigned int val, unsigned long arg)
336 {
337     void __user *argp = (void __user *)arg;
338
339     struct palacios_host_device_user *dev = fp->private_data;
340
341     DEEP_DEBUG_PRINT("palacios: hostdev: ioctl %u\n",val);
342     
343
344     if (!dev->connected) { 
345         ERROR("palacios: hostdev: ioctl on unconnected device\n");
346         return -EFAULT;
347     }
348     
349     switch (val) { 
350         case V3_HOST_DEV_USER_REQUEST_PUSH_IOCTL: {
351             
352             struct palacios_host_dev_user_op op;
353             
354             if (copy_from_user(&op,argp,sizeof(struct palacios_host_dev_user_op))) { 
355                 ERROR("palacios: unable to copy from user for host device \"%s\"\n",dev->url);
356                 return -EFAULT;
357             }
358
359             DEEP_DEBUG_PRINT("palacios: hostdev: user request push, type %d\n",op.type);
360             
361             switch (op.type) { 
362                 case PALACIOS_HOST_DEV_USER_REQUEST_READ_GUEST: {
363                     void *temp = kmalloc(op.len,GFP_KERNEL);
364
365                     DEEP_DEBUG_PRINT("palacios: hostdev: read guest\n");
366
367                     if (!temp) { 
368                         ERROR("palacios: unable to allocate enough for read guest request for host device \"%s\"\n",dev->url);
369                         return -EFAULT;
370                     }
371                     
372                     if (v3_host_dev_read_guest_mem(dev->guestdev,
373                                                    dev,
374                                                    op.gpa,
375                                                    temp,
376                                                    op.len) != op.len) {
377                         ERROR("palacios: unable to read enough from guest for host device \"%s\"\n",dev->url);
378                         kfree(temp);
379                         return -EFAULT;
380                     }
381                     
382                     if (copy_to_user(op.data,temp,op.len)) { 
383                         ERROR("palacios: unable to copy to user for host device \"%s\"\n",dev->url);
384                         kfree(temp);
385                         return -EFAULT;
386                     }
387
388                     kfree(temp);
389
390                     return op.len;
391                 }
392                     break;
393                     
394
395                 case PALACIOS_HOST_DEV_USER_REQUEST_WRITE_GUEST: {
396                     void *temp;
397                     
398                     DEEP_DEBUG_PRINT("palacios: hostdev: write guest\n");
399
400                     temp = kmalloc(op.len,GFP_KERNEL);
401
402                     if (!temp) { 
403                         ERROR("palacios: unable to allocate enough for write guest request for host device \"%s\"\n",dev->url);
404                         return -EFAULT;
405                     }
406                     
407                     if (copy_from_user(temp,op.data,op.len)) { 
408                         ERROR("palacios: unable to copy from user for host device \"%s\"\n",dev->url);
409                         kfree(temp);
410                         return -EFAULT;
411                     }
412                     
413                     if (v3_host_dev_write_guest_mem(dev->guestdev,
414                                                     dev,
415                                                     op.gpa,
416                                                     temp,
417                                                     op.len) != op.len) {
418                         ERROR("palacios: unable to write enough to guest for host device \"%s\"\n",dev->url);
419                         kfree(temp);
420                         return -EFAULT;
421                     }
422
423                     kfree(temp);
424                     
425                     return op.len;
426                 }
427                     break;
428
429                 case PALACIOS_HOST_DEV_USER_REQUEST_IRQ_GUEST: {
430
431                     DEEP_DEBUG_PRINT("palacios: hostdev: irq guest\n");
432
433                     return  v3_host_dev_raise_irq(dev->guestdev, dev, op.irq);
434                 }
435                     break;
436
437                 default:
438                     ERROR("palacios: unknown user request to host device \"%s\"\n",dev->url);
439                     return -EFAULT;
440                     break;
441             }
442         }
443             break;
444
445         case V3_HOST_DEV_HOST_REQUEST_SIZE_IOCTL: {
446             
447             unsigned long f;
448
449
450             DEEP_DEBUG_PRINT("palacios: hostdev: request size of request\n");
451             
452             spin_lock_irqsave(&(dev->lock),f);
453             
454             if (!(dev->waiting)) { 
455                 spin_unlock_irqrestore(&(dev->lock),f);
456                 DEEP_DEBUG_PRINT("palacios: hostdev: no request available\n");
457                 schedule();  // avoid livelock for polling user space process  SUSPICOUS
458                 return 0; // no request available now
459             } 
460             
461             if (copy_to_user(argp,&(dev->req->data_len),sizeof(uint64_t))) { 
462                 spin_unlock_irqrestore(&(dev->lock),f);
463                 ERROR("palacios: unable to copy to user for host device \"%s\"\n",dev->url);
464                 return -EFAULT; // failed to copy!
465
466             }
467             
468             spin_unlock_irqrestore(&(dev->lock),f);
469
470             DEEP_DEBUG_PRINT("palacios: hostdev: have request\n");
471
472             return 1; // have request for you
473             
474         }
475             
476             break;
477             
478         case V3_HOST_DEV_HOST_REQUEST_PULL_IOCTL: {
479             
480             unsigned long f;
481             
482             spin_lock_irqsave(&(dev->lock),f);
483             
484             DEEP_DEBUG_PRINT("palacios: hostdev: pull request\n");
485
486             if (!(dev->waiting) || !(dev->req)) { 
487                 spin_unlock_irqrestore(&(dev->lock),f);
488                 DEEP_DEBUG_PRINT("palacios: hostdev: no request to pull\n");
489                 return 0; // no request available now
490             } 
491
492             
493             if (copy_to_user(argp,dev->req,dev->req->data_len)) { 
494                 spin_unlock_irqrestore(&(dev->lock),f);
495                 ERROR("palacios: unable to copy to user for host device \"%s\"\n",dev->url);
496                 return -EFAULT; // failed to copy!
497             }
498     
499             spin_unlock_irqrestore(&(dev->lock),f);
500
501             DEEP_DEBUG_PRINT("palacios: hostdev: request pulled\n");
502             
503             return 1; // copied request for you
504         }
505             break;
506             
507         case V3_HOST_DEV_USER_RESPONSE_PUSH_IOCTL: {
508
509             unsigned long f;
510             uint64_t user_datalen;
511             uint64_t old_len;
512             
513             spin_lock_irqsave(&(dev->lock),f);
514             
515             DEEP_DEBUG_PRINT("palacios: hostdev: push response\n");
516
517             if (!(dev->waiting)) { 
518                 spin_unlock_irqrestore(&(dev->lock),f);
519                 ERROR("palacios: hostdev: no matching request for pushed response\n");
520                 return 0; // no request outstanding, so we do not need a response!
521             }
522             
523             if (copy_from_user(&user_datalen,argp,sizeof(uint64_t))) { 
524                 spin_unlock_irqrestore(&(dev->lock),f);
525                 ERROR("palacios: unable to copy from user for host device \"%s\"\n",dev->url);
526                 return -EFAULT; // failed to copy!
527             } 
528
529             if (user_datalen<sizeof(struct palacios_host_dev_host_request_response)) { 
530                 // bad user
531                 spin_unlock_irqrestore(&(dev->lock),f);
532                 ERROR("palacios: user has response that is too small on host device \"%s\"\n",dev->url);
533                 return -EFAULT;
534             }
535
536             if (!palacios_bigenough_reqresp(dev->resp,user_datalen-sizeof(struct palacios_host_dev_host_request_response))) {
537                 // not enough room.
538                 // we drop the lock, turn on interrupts, resize, and then retry
539                 DEEP_DEBUG_PRINT("palacios: response not big enough, dropping lock to resize on device \"%s\"\n",dev->url);
540
541                 spin_unlock_irqrestore(&(dev->lock),f);
542                 
543                 if (palacios_resize_reqresp(&(dev->resp),user_datalen-sizeof(struct palacios_host_dev_host_request_response),0)) {
544                     ERROR("palacios: unable to resize to accept response of size %llu from user for host device \"%s\"\n",user_datalen,dev->url);
545                     return -EFAULT;
546                 } else {
547                     // reacquire the lock
548                     // There shouldn't be a race here, since there should
549                     // be exactly one user space thread giving us a response for this device
550                     // and it is blocked waiting for us to finish
551                     spin_lock_irqsave(&(dev->lock),f);
552                     DEEP_DEBUG_PRINT("palacios: reacuired lock on device \"%s\"\n",dev->url);
553                 }
554             }
555
556             //We only copy data_len bytes from user, but we will
557             //overwrite the len field, so we preserve and then restore
558             old_len = dev->resp->len;
559             if (copy_from_user(dev->resp, argp, user_datalen)) { 
560                 dev->resp->len=old_len;
561                 spin_unlock_irqrestore(&(dev->lock),f);
562                 ERROR("palacios: unable to copy from user for host device \"%s\"\n",dev->url);
563                 return -EFAULT; // failed to copy!
564             } 
565             dev->resp->len=old_len;
566             
567             DEEP_DEBUG_PRINT("palacios: hostdev: valid response pushed\n");
568             // now have valid response!
569             dev->waiting=0;
570
571             spin_unlock_irqrestore(&(dev->lock),f);
572
573             // wake the palacios side up so that it sees it
574             cycle_response_request(dev);
575
576             return 1; // done
577         }
578             break;
579             
580         default:
581             ERROR("palacios: unknown ioctl for host device \"%s\"\n",dev->url);
582             return -EFAULT;
583             break;
584     }
585     
586 }
587
588
589
590
591 static struct file_operations host_dev_fops = {
592     .poll     = host_dev_poll,
593     .release  = host_dev_release,
594     .ioctl    = host_dev_ioctl,
595 };
596
597
598
599     
600 int connect_host_dev(struct v3_guest * guest, char *url) 
601 {
602     struct palacios_host_device_user *dev;
603     unsigned long f1, f2;
604     int i;
605
606     // currently only support user: types:
607     if (strncasecmp(url,"user:",5)) { 
608         ERROR("palacios: do not currently support host devices of type in \"%s\"\n",url);
609         return -1;
610     }
611     
612     INFO("palacios: attempting to rendezvous with palacios side of host device \"%s\"\n",url);
613     
614     // We will scan the list looking for the relevant
615     // URL.  If we don't find it after a while, we give up
616     
617     for (i=0;i<RENDEZVOUS_WAIT_SECS/RENDEZVOUS_RETRY_SECS;i++) { 
618         spin_lock_irqsave(&(guest->hostdev.lock),f1);
619         list_for_each_entry(dev,&(guest->hostdev.devs), node) {
620             if (!strncasecmp(url,dev->url,MAX_URL)) { 
621                 // found it
622                 spin_lock_irqsave(&(dev->lock),f2);
623                 if (dev->connected) { 
624                     ERROR("palacios: device for \"%s\" is already connected!\n",url);
625                     spin_unlock_irqrestore(&(dev->lock),f2);
626                     spin_unlock_irqrestore(&(guest->hostdev.lock),f1);
627                     return -1;
628                 } else {
629                     dev->fd = anon_inode_getfd("v3-hostdev", &host_dev_fops, dev, 0);
630                     if (dev->fd<0) { 
631                         ERROR("palacios: cannot create fd for device \"%s\"\n",url);
632                         spin_unlock_irqrestore(&(dev->lock),f2);
633                         spin_unlock_irqrestore(&(guest->hostdev.lock),f1);
634                         return -1;
635                     }
636                     dev->connected=1;
637                     dev->waiting=0;
638                     if (dev->req) { 
639                         kfree(dev->req);
640                         dev->req=0;
641                     } 
642                     if (dev->resp) { 
643                         kfree(dev->resp);
644                         dev->resp=0;
645                     }
646                     INFO("palacios: connected fd for device \"%s\"\n",url);
647                     spin_unlock_irqrestore(&(dev->lock),f2);
648                     spin_unlock_irqrestore(&(guest->hostdev.lock),f1);
649                     return dev->fd;
650                 }
651                 spin_unlock_irqrestore(&(dev->lock),f2);
652             }
653         }
654         spin_unlock_irqrestore(&(guest->hostdev.lock),f1);
655         
656         ssleep(RENDEZVOUS_RETRY_SECS);
657     }
658     
659     ERROR("palacios: timeout waiting for connection for device \"%s\"",url);
660     
661     return -1;
662     
663 }
664
665
666
667
668
669
670
671
672 /***************************************************************************************
673
674    Following this is the implementation of the palacios->host interface
675
676 **************************************************************************************/
677
678 static v3_host_dev_t palacios_host_dev_open(char *url,
679                                             v3_bus_class_t bus,
680                                             v3_guest_dev_t gdev,
681                                             void *host_priv_data)
682 {
683     struct v3_guest *guest= (struct v3_guest*)host_priv_data;
684     struct palacios_host_device_user *dev;
685     unsigned long f1,f2;
686     int i;
687
688     /*
689       I will create the device in the list and then wait
690       for the user side to attach
691     */
692
693
694     if (strncasecmp(url,"user:",5)) { 
695         ERROR("palacios: do not currently support devices of type in \"%s\"\n",url);
696         return NULL;
697     }
698
699     // Check to see if a device of this url already exists, which would be ugly
700     spin_lock_irqsave(&(guest->hostdev.lock),f1);
701     list_for_each_entry(dev,&(guest->hostdev.devs), node) {
702         if (!strncasecmp(url,dev->url,MAX_URL)) { 
703             // found it
704             spin_unlock_irqrestore(&(guest->hostdev.lock),f1);
705             ERROR("palacios: a host device with url \"%s\" already exists in the guest!\n",url);
706             return NULL;
707         }
708     }
709     spin_unlock_irqrestore(&(guest->hostdev.lock),f1);
710
711
712     INFO("palacios: creating host device \"%s\"\n",url);
713
714     dev = kmalloc(sizeof(struct palacios_host_device_user),GFP_KERNEL);
715     
716     if (!dev) { 
717         ERROR("palacios: cannot allocate for host device \"%s\"\n",url);
718         return NULL;
719     }
720
721     memset(dev,0,sizeof(struct palacios_host_device_user));
722     
723     strncpy(dev->url,url,MAX_URL);
724     
725     dev->guestdev=gdev;
726     
727     dev->guest=guest;
728
729     spin_lock_init(&(dev->lock));
730
731     init_waitqueue_head(&(dev->user_wait_queue));
732     init_waitqueue_head(&(dev->host_wait_queue));
733
734     INFO("palacios: attempting to rendezvous with user side of host device \"%s\"\n",url);
735     
736     // Insert ourselves into the list
737     spin_lock_irqsave(&(guest->hostdev.lock),f1);
738     list_add(&(dev->node),&(guest->hostdev.devs));
739     spin_unlock_irqrestore(&(guest->hostdev.lock),f1);
740
741     
742     // Now wait until we are noticed!
743     for (i=0;i<RENDEZVOUS_WAIT_SECS/RENDEZVOUS_RETRY_SECS;i++) { 
744         spin_lock_irqsave(&(dev->lock),f2);
745         if (dev->connected){ 
746             INFO("palacios: connection with user side established for host device \"%s\" fd=%d\n",dev->url,dev->fd);
747             spin_unlock_irqrestore(&(dev->lock),f2);
748             return dev;
749         }
750         spin_unlock_irqrestore(&(dev->lock),f2);
751         ssleep(RENDEZVOUS_RETRY_SECS);
752     }
753     
754     ERROR("palacios: timeout waiting for user side to connect to host device \"%s\"",url);
755     
756     // get us out of the list
757     spin_lock_irqsave(&(guest->hostdev.lock),f1);
758     list_del(&(dev->node));
759     spin_unlock_irqrestore(&(guest->hostdev.lock),f1);
760     
761     palacios_host_dev_user_free(dev);
762     
763     return NULL;
764 }
765
766 static int palacios_host_dev_close(v3_host_dev_t hostdev)
767 {
768     unsigned long f1, f2;
769
770     struct palacios_host_device_user *dev = (struct palacios_host_device_user *) hostdev;
771     
772     INFO("palacios: closing host device \"%s\"\n",dev->url);
773
774     spin_lock_irqsave(&(dev->guest->hostdev.lock),f1);
775
776     spin_lock_irqsave(&(dev->lock),f2);
777
778     if (dev->connected) { 
779         dev->connected=0;
780         // After this, any user side request will return -EFAULT
781     }
782
783     list_del(&(dev->node));
784     
785     spin_unlock_irqrestore(&(dev->lock),f2);
786     spin_unlock_irqrestore(&(dev->guest->hostdev.lock),f1);
787     
788     palacios_host_dev_user_free(dev);
789
790     return 0;
791 }
792
793
794
795         
796 static uint64_t palacios_host_dev_read_io(v3_host_dev_t hostdev,
797                                           uint16_t      port,
798                                           void          *dest,
799                                           uint64_t      len)
800 {
801     struct palacios_host_device_user *dev = (struct palacios_host_device_user *)hostdev;
802     unsigned long f;
803     uint64_t op_len;
804
805     DEEP_DEBUG_PRINT("palacios: hostdev: read io port 0x%x\n",port);
806             
807
808     spin_lock_irqsave(&(dev->lock),f);
809     
810     if (dev->waiting) { 
811         spin_unlock_irqrestore(&(dev->lock),f);
812         ERROR("palacios: guest issued i/o read request with host device \"%s\" in wrong state (waiting=%d, connected=%d)\n",dev->url,dev->waiting,dev->connected);
813         return 0;
814     }
815
816     if (!dev->connected) {
817         spin_unlock_irqrestore(&(dev->lock),f);
818         ERROR("palacios: ignoring request as user side is not connected for host device \"%s\"\n",dev->url);
819         return 0;
820     }
821     
822     
823     // resize request (no data)
824     if (!palacios_bigenough_reqresp(dev->req,0)) {
825         // not enough room.
826         // we drop the lock, turn on interrupts, resize, and then retry
827         DEEP_DEBUG_PRINT("palacios: request not big enough, dropping lock to resize on device \"%s\"\n",dev->url);
828         
829         spin_unlock_irqrestore(&(dev->lock),f);
830         
831         if (palacios_resize_reqresp(&(dev->req),0,0)) {
832             ERROR("palacios: cannot resize for request on device \"%s\"\n",dev->url);
833             return 0;
834         } else {
835             // reacquire the lock
836             // There shouldn't be a race here since there should not be another
837             // request from palacios until this one finishes
838             spin_lock_irqsave(&(dev->lock),f);
839             DEEP_DEBUG_PRINT("palacios: reacquired lock on device \"%s\"\n",dev->url);
840         }
841     }
842     
843
844     dev->req->type=PALACIOS_HOST_DEV_HOST_REQUEST_READ_IO;
845     dev->req->port=port;
846     dev->req->op_len=len;
847     dev->req->gpa=0;
848     dev->req->conf_addr=0;
849     dev->req->data_len=sizeof(struct palacios_host_dev_host_request_response);
850
851     dev->waiting=1;
852     
853     spin_unlock_irqrestore(&(dev->lock),f);
854
855     // hand over to the user space and wait for it to respond
856     cycle_request_response(dev);
857
858     // We're back!   So now we'll hand the response back to Palacios
859
860     spin_lock_irqsave(&(dev->lock),f);
861
862     op_len = dev->resp->op_len < len ? dev->resp->op_len : len ;
863
864     memcpy(dest,dev->resp->data, op_len);
865     
866     spin_unlock_irqrestore(&(dev->lock),f);
867
868     return op_len;
869 }
870
871 static uint64_t palacios_host_dev_read_mem(v3_host_dev_t hostdev,
872                                            void *        gpa,
873                                            void          *dest,
874                                            uint64_t      len)
875 {
876     struct palacios_host_device_user *dev = (struct palacios_host_device_user *)hostdev;
877     unsigned long f;
878     uint64_t op_len;
879
880     DEEP_DEBUG_PRINT("palacios: hostdev: read mem  0x%p\n",gpa);
881
882     spin_lock_irqsave(&(dev->lock),f);
883     
884     if (dev->waiting) { 
885         spin_unlock_irqrestore(&(dev->lock),f);
886         ERROR("palacios: guest issued memory read request with host device \"%s\" in wrong state (waiting=%d, connected=%d)\n",dev->url,dev->waiting,dev->connected);
887         return 0;
888     }
889     if (!dev->connected) {
890         spin_unlock_irqrestore(&(dev->lock),f);
891         ERROR("palacios: ignoring request as user side is not connected for host device \"%s\"\n",dev->url);
892         return 0;
893     }
894     
895     // resize request (no data)
896     if (!palacios_bigenough_reqresp(dev->req,0)) {
897         // not enough room.
898         // we drop the lock, turn on interrupts, resize, and then retry
899         DEEP_DEBUG_PRINT("palacios: request not big enough, dropping lock to resize on device \"%s\"\n",dev->url);
900         
901         spin_unlock_irqrestore(&(dev->lock),f);
902         
903         if (palacios_resize_reqresp(&(dev->req),0,0)) {
904             ERROR("palacios: cannot resize for request on device \"%s\"\n",dev->url);
905             return 0;
906         } else {
907             // reacquire the lock
908             // There shouldn't be a race here since there should not be another
909             // request from palacios until this one finishes
910             spin_lock_irqsave(&(dev->lock),f);
911             DEEP_DEBUG_PRINT("palacios: reacquired lock on device \"%s\"\n",dev->url);
912         }
913     }
914
915     dev->req->type=PALACIOS_HOST_DEV_HOST_REQUEST_READ_MEM;
916     dev->req->port=0;
917     dev->req->op_len=len;
918     dev->req->gpa=gpa;
919     dev->req->conf_addr=0;
920     dev->req->data_len=sizeof(struct palacios_host_dev_host_request_response);
921
922     dev->waiting=1;
923     
924     spin_unlock_irqrestore(&(dev->lock),f);
925
926     // hand over to the user space and wait for it to respond
927     cycle_request_response(dev);
928
929     // We're back!   So now we'll hand the response back to Palacios
930
931     spin_lock_irqsave(&(dev->lock),f);
932
933     op_len = dev->resp->op_len < len ? dev->resp->op_len : len ;
934
935     memcpy(dest,dev->resp->data, op_len);
936     
937     spin_unlock_irqrestore(&(dev->lock),f);
938
939     return op_len;
940 }
941
942 static uint64_t palacios_host_dev_read_conf(v3_host_dev_t hostdev,
943                                             uint64_t      offset,
944                                             void          *dest,
945                                             uint64_t      len)
946 {
947     struct palacios_host_device_user *dev = (struct palacios_host_device_user *)hostdev;
948     unsigned long f;
949     uint64_t op_len;
950
951     DEEP_DEBUG_PRINT("palacios: hostdev: read conf 0x%p\n",(void*)offset);
952
953     spin_lock_irqsave(&(dev->lock),f);
954     
955     if (dev->waiting) { 
956         spin_unlock_irqrestore(&(dev->lock),f);
957         ERROR("palacios: guest issued config read request with host device \"%s\" in wrong state (waiting=%d, connected=%d)\n",dev->url,dev->waiting,dev->connected);
958         return 0;
959     }
960     if (!dev->connected) {
961         spin_unlock_irqrestore(&(dev->lock),f);
962         ERROR("palacios: ignoring request as user side is not connected for host device \"%s\"\n",dev->url);
963         return 0;
964     }
965     
966     // resize request (no data)
967     if (!palacios_bigenough_reqresp(dev->req,0)) {
968         // not enough room.
969         // we drop the lock, turn on interrupts, resize, and then retry
970         DEEP_DEBUG_PRINT("palacios: request not big enough, dropping lock to resize on device \"%s\"\n",dev->url);
971         
972         spin_unlock_irqrestore(&(dev->lock),f);
973         
974         if (palacios_resize_reqresp(&(dev->req),0,0)) {
975             ERROR("palacios: cannot resize for request on device \"%s\"\n",dev->url);
976             return 0;
977         } else {
978             // reacquire the lock
979             // There shouldn't be a race here since there should not be another
980             // request from palacios until this one finishes
981             spin_lock_irqsave(&(dev->lock),f);
982             DEEP_DEBUG_PRINT("palacios: reacquired lock on device \"%s\"\n",dev->url);
983         }
984     }
985
986     dev->req->type=PALACIOS_HOST_DEV_HOST_REQUEST_READ_CONF;
987     dev->req->port=0;
988     dev->req->op_len=len;
989     dev->req->gpa=0;
990     dev->req->conf_addr=offset;
991     dev->req->data_len=sizeof(struct palacios_host_dev_host_request_response);
992
993     dev->waiting=1;
994     
995     spin_unlock_irqrestore(&(dev->lock),f);
996
997     // hand over to the user space and wait for it to respond
998     cycle_request_response(dev);
999
1000     // We're back!   So now we'll hand the response back to Palacios
1001
1002     spin_lock_irqsave(&(dev->lock),f);
1003
1004     op_len = dev->resp->op_len < len ? dev->resp->op_len : len ;
1005
1006     memcpy(dest,dev->resp->data, op_len);
1007     
1008     spin_unlock_irqrestore(&(dev->lock),f);
1009
1010     return op_len;
1011 }
1012
1013
1014 static uint64_t palacios_host_dev_write_io(v3_host_dev_t hostdev,
1015                                            uint16_t      port,
1016                                            void          *src,
1017                                            uint64_t      len)
1018 {
1019     struct palacios_host_device_user *dev = (struct palacios_host_device_user *)hostdev;
1020     unsigned long f;
1021     uint64_t op_len;
1022
1023     DEEP_DEBUG_PRINT("palacios: hostdev: write io port 0x%x \n",port);
1024
1025     spin_lock_irqsave(&(dev->lock),f);
1026     
1027     if (dev->waiting) { 
1028         spin_unlock_irqrestore(&(dev->lock),f);
1029         ERROR("palacios: guest issued i/o write request with host device \"%s\" in wrong state (waiting=%d, connected=%d)\n",dev->url,dev->waiting,dev->connected);
1030         return 0;
1031     }
1032     if (!dev->connected) {
1033         spin_unlock_irqrestore(&(dev->lock),f);
1034         ERROR("palacios: ignoring request as user side is not connected for host device \"%s\"\n",dev->url);
1035         return 0;
1036     }
1037
1038     // resize request 
1039     if (!palacios_bigenough_reqresp(dev->req,len)) {
1040         // not enough room.
1041         // we drop the lock, turn on interrupts, resize, and then retry
1042         DEEP_DEBUG_PRINT("palacios: request not big enough, dropping lock to resize on device \"%s\"\n",dev->url);
1043         
1044         spin_unlock_irqrestore(&(dev->lock),f);
1045         
1046         if (palacios_resize_reqresp(&(dev->req),len,0)) {
1047             ERROR("palacios: cannot resize for request on device \"%s\"\n",dev->url);
1048             return 0;
1049         } else {
1050             // reacquire the lock
1051             // There shouldn't be a race here since there should not be another
1052             // request from palacios until this one finishes
1053             spin_lock_irqsave(&(dev->lock),f);
1054             DEEP_DEBUG_PRINT("palacios: reacquired lock on device \"%s\"\n",dev->url);
1055         }
1056     }
1057
1058     dev->req->type=PALACIOS_HOST_DEV_HOST_REQUEST_WRITE_IO;
1059     dev->req->port=port;
1060     dev->req->op_len=len;
1061     dev->req->gpa=0;
1062     dev->req->conf_addr=0;
1063     dev->req->data_len=sizeof(struct palacios_host_dev_host_request_response)+len;
1064
1065     memcpy(dev->req->data,src,len);
1066
1067     dev->waiting=1;
1068
1069     spin_unlock_irqrestore(&(dev->lock),f);
1070    
1071     // hand over to the user space and wait for it to respond
1072     cycle_request_response(dev);
1073
1074     // We're back!   So now we'll hand the response back to Palacios
1075
1076     spin_lock_irqsave(&(dev->lock),f);
1077
1078     op_len = dev->resp->op_len < len ? dev->resp->op_len : len ;
1079
1080     spin_unlock_irqrestore(&(dev->lock),f);
1081
1082     return op_len;
1083 }
1084
1085
1086 static uint64_t palacios_host_dev_write_mem(v3_host_dev_t hostdev,
1087                                             void *        gpa,
1088                                             void          *src,
1089                                             uint64_t      len)
1090 {
1091     struct palacios_host_device_user *dev = (struct palacios_host_device_user *)hostdev;
1092     unsigned long f;
1093     uint64_t op_len;
1094
1095     DEEP_DEBUG_PRINT("palacios: hostdev: write mem 0x%p\n",gpa);
1096
1097     spin_lock_irqsave(&(dev->lock),f);
1098     
1099     if (dev->waiting) { 
1100         spin_unlock_irqrestore(&(dev->lock),f);
1101         ERROR("palacios: guest issued memory write request with host device \"%s\" in wrong state (waiting=%d, connected=%d)\n",dev->url,dev->waiting,dev->connected);
1102         return 0;
1103     }
1104     if (!dev->connected) {
1105         spin_unlock_irqrestore(&(dev->lock),f);
1106         ERROR("palacios: ignoring request as user side is not connected for host device \"%s\"\n",dev->url);
1107         return 0;
1108     }
1109     
1110     // resize request 
1111     if (!palacios_bigenough_reqresp(dev->req,len)) {
1112         // not enough room.
1113         // we drop the lock, turn on interrupts, resize, and then retry
1114         DEEP_DEBUG_PRINT("palacios: request not big enough, dropping lock to resize on device \"%s\"\n",dev->url);
1115         
1116         spin_unlock_irqrestore(&(dev->lock),f);
1117         
1118         if (palacios_resize_reqresp(&(dev->req),len,0)) {
1119             ERROR("palacios: cannot resize for request on device \"%s\"\n",dev->url);
1120             return 0;
1121         } else {
1122             // reacquire the lock
1123             // There shouldn't be a race here since there should not be another
1124             // request from palacios until this one finishes
1125             spin_lock_irqsave(&(dev->lock),f);
1126             DEEP_DEBUG_PRINT("palacios: reacquired lock on device \"%s\"\n",dev->url);
1127         }
1128     }
1129
1130     dev->req->type=PALACIOS_HOST_DEV_HOST_REQUEST_WRITE_MEM;
1131     dev->req->port=0;
1132     dev->req->op_len=len;
1133     dev->req->gpa=gpa;
1134     dev->req->conf_addr=0;
1135     dev->req->data_len=sizeof(struct palacios_host_dev_host_request_response)+len;
1136
1137     memcpy(dev->req->data,src,len);
1138
1139     dev->waiting=1;
1140     
1141     spin_unlock_irqrestore(&(dev->lock),f);
1142
1143     // hand over to the user space and wait for it to respond
1144     cycle_request_response(dev);
1145
1146     // We're back!   So now we'll hand the response back to Palacios
1147
1148     spin_lock_irqsave(&(dev->lock),f);
1149
1150     op_len= dev->resp->op_len < len ? dev->resp->op_len : len ;
1151
1152     spin_unlock_irqrestore(&(dev->lock),f);
1153
1154     return op_len;
1155 }
1156
1157
1158
1159
1160 static uint64_t palacios_host_dev_write_conf(v3_host_dev_t hostdev,
1161                                              uint64_t      offset,
1162                                              void          *src,
1163                                              uint64_t      len)
1164 {
1165     struct palacios_host_device_user *dev = (struct palacios_host_device_user *)hostdev;
1166     unsigned long f;
1167     uint64_t op_len;
1168
1169     DEEP_DEBUG_PRINT("palacios: hostdev: write conf 0x%p\n",(void*)offset);
1170
1171     spin_lock_irqsave(&(dev->lock),f);
1172     
1173     if (dev->waiting) { 
1174         spin_unlock_irqrestore(&(dev->lock),f);
1175         ERROR("palacios: guest issued config write request with host device \"%s\" in wrong state (waiting=%d, connected=%d)\n",dev->url,dev->waiting,dev->connected);
1176         return 0;
1177     }
1178     if (!dev->connected) {
1179         spin_unlock_irqrestore(&(dev->lock),f);
1180         ERROR("palacios: ignoring request as user side is not connected for host device \"%s\"\n",dev->url);
1181         return 0;
1182     }
1183     
1184     // resize request 
1185     if (!palacios_bigenough_reqresp(dev->req,len)) {
1186         // not enough room.
1187         // we drop the lock, turn on interrupts, resize, and then retry
1188         DEEP_DEBUG_PRINT("palacios: request not big enough, dropping lock to resize on device \"%s\"\n",dev->url);
1189         
1190         spin_unlock_irqrestore(&(dev->lock),f);
1191         
1192         if (palacios_resize_reqresp(&(dev->req),len,0)) {
1193             ERROR("palacios: cannot resize for request on device \"%s\"\n",dev->url);
1194             return 0;
1195         } else {
1196             // reacquire the lock
1197             // There shouldn't be a race here since there should not be another
1198             // request from palacios until this one finishes
1199             spin_lock_irqsave(&(dev->lock),f);
1200             DEEP_DEBUG_PRINT("palacios: reacquired lock on device \"%s\"\n",dev->url);
1201         }
1202     }
1203
1204     dev->req->type=PALACIOS_HOST_DEV_HOST_REQUEST_WRITE_CONF;
1205     dev->req->port=0;
1206     dev->req->op_len=len;
1207     dev->req->gpa=0;
1208     dev->req->conf_addr=offset;
1209     dev->req->data_len=sizeof(struct palacios_host_dev_host_request_response)+len;
1210
1211     memcpy(dev->req->data,src,len);
1212
1213     dev->waiting=1;
1214     
1215     spin_unlock_irqrestore(&(dev->lock),f);
1216
1217     // hand over to the user space and wait for it to respond
1218     cycle_request_response(dev);
1219
1220     // We're back!   So now we'll hand the response back to Palacios
1221
1222     spin_lock_irqsave(&(dev->lock),f);
1223
1224     op_len = dev->resp->op_len < len ? dev->resp->op_len : len ;
1225
1226     spin_unlock_irqrestore(&(dev->lock),f);
1227
1228     return op_len;
1229 }
1230  
1231  
1232 static int palacios_host_dev_ack_irq(v3_host_dev_t hostdev, uint8_t irq)
1233 {
1234     // we don't care
1235     return 0;
1236 }
1237  
1238
1239
1240
1241
1242 static struct v3_host_dev_hooks palacios_host_dev_hooks = {
1243     .open                       = palacios_host_dev_open,
1244     .close                      = palacios_host_dev_close,
1245     .read_io                    = palacios_host_dev_read_io,
1246     .write_io                   = palacios_host_dev_write_io,
1247     .read_mem                   = palacios_host_dev_read_mem,
1248     .write_mem                  = palacios_host_dev_write_mem,
1249     .read_config                = palacios_host_dev_read_conf,
1250     .write_config               = palacios_host_dev_write_conf,
1251     .ack_irq                    = palacios_host_dev_ack_irq,
1252 };
1253
1254
1255
1256 int palacios_init_host_dev( void ) 
1257 {
1258     V3_Init_Host_Device_Support(&palacios_host_dev_hooks);
1259     
1260     return 0;
1261 }