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.


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