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.


Clean up compat ioctl handlers in host-dev and keyed-stream host ifaces
[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 #endif
609     .ioctl = host_dev_ioctl,
610 };
611
612
613
614 static int host_dev_connect(struct v3_guest * guest, unsigned int cmd, unsigned long arg, void * priv_data) 
615 {
616     void __user * argp = (void __user *)arg;
617     char url[MAX_URL];
618     struct palacios_host_dev * host_dev = priv_data;
619     struct palacios_host_device_user *dev;
620     unsigned long f1, f2;
621     int i;
622
623
624
625     if (copy_from_user(url, argp, MAX_URL)) {
626         printk("copy from user error getting url for host device connect...\n");
627         return -EFAULT;
628     }
629
630     // currently only support user: types:
631     if (strncasecmp(url,"user:",5)) { 
632         ERROR("palacios: do not currently support host devices of type in \"%s\"\n",url);
633         return -1;
634     }
635     
636     INFO("palacios: attempting to rendezvous with palacios side of host device \"%s\"\n",url);
637     
638     // We will scan the list looking for the relevant
639     // URL.  If we don't find it after a while, we give up
640     
641     for (i=0;i<RENDEZVOUS_WAIT_SECS/RENDEZVOUS_RETRY_SECS;i++) { 
642         spin_lock_irqsave(&(host_dev->lock),f1);
643         list_for_each_entry(dev,&(host_dev->devs), node) {
644             if (!strncasecmp(url,dev->url,MAX_URL)) { 
645                 // found it
646                 spin_lock_irqsave(&(dev->lock),f2);
647                 if (dev->connected) { 
648                     ERROR("palacios: device for \"%s\" is already connected!\n",url);
649                     spin_unlock_irqrestore(&(dev->lock),f2);
650                     spin_unlock_irqrestore(&(host_dev->lock),f1);
651                     return -1;
652                 } else {
653                     dev->fd = anon_inode_getfd("v3-hostdev", &host_dev_fops, dev, 0);
654                     if (dev->fd<0) { 
655                         ERROR("palacios: cannot create fd for device \"%s\"\n",url);
656                         spin_unlock_irqrestore(&(dev->lock),f2);
657                         spin_unlock_irqrestore(&(host_dev->lock),f1);
658                         return -1;
659                     }
660                     dev->connected=1;
661                     dev->waiting=0;
662                     if (dev->req) { 
663                         kfree(dev->req);
664                         dev->req=0;
665                     } 
666                     if (dev->resp) { 
667                         kfree(dev->resp);
668                         dev->resp=0;
669                     }
670                     INFO("palacios: connected fd for device \"%s\"\n",url);
671                     spin_unlock_irqrestore(&(dev->lock),f2);
672                     spin_unlock_irqrestore(&(host_dev->lock),f1);
673                     return dev->fd;
674                 }
675                 spin_unlock_irqrestore(&(dev->lock),f2);
676             }
677         }
678         spin_unlock_irqrestore(&(host_dev->lock),f1);
679         
680         ssleep(RENDEZVOUS_RETRY_SECS);
681     }
682     
683     ERROR("palacios: timeout waiting for connection for device \"%s\"",url);
684     
685     return -1;
686     
687 }
688
689
690
691
692
693
694
695
696 /***************************************************************************************
697
698    Following this is the implementation of the palacios->host interface
699
700 **************************************************************************************/
701
702
703 /* Attempt to rendezvous with the user device if no device is currently connected */
704 static int palacios_host_dev_rendezvous(struct palacios_host_device_user *dev)
705 {
706     unsigned long f;
707     int i;
708
709     if (dev->connected) { 
710         return 0;
711     }
712
713    
714     INFO("palacios: attempting new rendezvous for host device \"%s\"\n",dev->url);
715
716     // Now wait until we are noticed!
717     for (i=0;i<RENDEZVOUS_WAIT_SECS/RENDEZVOUS_RETRY_SECS;i++) { 
718         spin_lock_irqsave(&(dev->lock),f);
719         if (dev->connected) { 
720             INFO("palacios: connection with user side established for host device \"%s\" fd=%d\n",dev->url,dev->fd);
721             spin_unlock_irqrestore(&(dev->lock),f);
722             return 0;
723         }
724         spin_unlock_irqrestore(&(dev->lock),f);
725         ssleep(RENDEZVOUS_RETRY_SECS);
726     }
727     
728     ERROR("palacios: timeout waiting for user side to connect to host device \"%s\"",dev->url);
729
730     // We stay in the list because a future rendezvous might happen
731     
732     return -1;
733 }
734
735
736 /* Creates the device without rendezvous */
737 static v3_host_dev_t palacios_host_dev_open_deferred(char *url,
738                                                      v3_bus_class_t bus,
739                                                      v3_guest_dev_t gdev,
740                                                      void *host_priv_data)
741 {
742     struct v3_guest *guest= (struct v3_guest*)host_priv_data;
743     struct palacios_host_device_user *dev;
744     struct palacios_host_dev * host_dev = NULL;
745     unsigned long f;
746
747     /*
748       I will create the device in the list and then wait
749       for the user side to attach
750     */
751
752     if (guest == NULL) {
753         return 0;
754     }
755     
756
757     host_dev = get_vm_ext_data(guest, "HOST_DEVICE_INTERFACE");
758
759     if (host_dev == NULL) {
760         printk("Error locating vm host data for HOST_DEVICE_INTERFACE\n");
761         return 0;
762     }
763
764
765     if (strncasecmp(url,"user:",5)) { 
766         ERROR("palacios: do not currently support devices of type in \"%s\"\n",url);
767         return NULL;
768     }
769
770     // Check to see if a device of this url already exists, which would be ugly
771     spin_lock_irqsave(&(host_dev->lock),f);
772     list_for_each_entry(dev,&(host_dev->devs), node) {
773         if (!strncasecmp(url,dev->url,MAX_URL)) { 
774             // found it
775             spin_unlock_irqrestore(&(host_dev->lock),f);
776             ERROR("palacios: a host device with url \"%s\" already exists in the guest!\n",url);
777             return NULL;
778         }
779     }
780     spin_unlock_irqrestore(&(host_dev->lock),f);
781
782
783     INFO("palacios: creating host device \"%s\"\n",url);
784
785     dev = kmalloc(sizeof(struct palacios_host_device_user),GFP_KERNEL);
786     
787     if (!dev) { 
788         ERROR("palacios: cannot allocate for host device \"%s\"\n",url);
789         return NULL;
790     }
791
792     memset(dev,0,sizeof(struct palacios_host_device_user));
793     
794     strncpy(dev->url,url,MAX_URL);
795     
796     dev->guestdev = gdev;
797     
798     dev->guest = guest;
799
800     spin_lock_init(&(dev->lock));
801
802     init_waitqueue_head(&(dev->user_wait_queue));
803     init_waitqueue_head(&(dev->host_wait_queue));
804
805     // Insert ourselves into the list
806     spin_lock_irqsave(&(host_dev->lock),f);
807     list_add(&(dev->node),&(host_dev->devs));
808     spin_unlock_irqrestore(&(host_dev->lock),f);
809
810     INFO("palacios: host device \"%s\" created with deferred rendezvous\n",url);
811
812     return dev;
813
814 }
815
816
817
818 static int palacios_host_dev_close(v3_host_dev_t hostdev)
819 {
820     unsigned long f1, f2;
821
822     struct palacios_host_device_user *dev = (struct palacios_host_device_user *) hostdev;
823     struct palacios_host_dev * host_dev = NULL;
824
825     INFO("palacios: closing host device \"%s\"\n",dev->url);
826
827     if ((dev == NULL) || (dev->guest == NULL)) {
828         return -1;
829     }
830
831     host_dev = get_vm_ext_data(dev->guest, "HOST_DEVICE_INTERFACE");
832
833     
834     if (host_dev == NULL) {
835         return -1;
836     }
837
838     spin_lock_irqsave(&(host_dev->lock),f1);
839
840     spin_lock_irqsave(&(dev->lock),f2);
841
842     if (dev->connected) { 
843         dev->connected=0;
844         // After this, any user side request will return -EFAULT
845     }
846
847     list_del(&(dev->node));
848     
849     spin_unlock_irqrestore(&(dev->lock),f2);
850     spin_unlock_irqrestore(&(host_dev->lock),f1);
851     
852     palacios_host_dev_user_free(dev);
853
854     return 0;
855 }
856
857
858
859         
860 static uint64_t palacios_host_dev_read_io(v3_host_dev_t hostdev,
861                                           uint16_t      port,
862                                           void          *dest,
863                                           uint64_t      len)
864 {
865     struct palacios_host_device_user *dev = (struct palacios_host_device_user *)hostdev;
866     unsigned long f;
867     uint64_t op_len;
868
869     DEEP_DEBUG_PRINT("palacios: hostdev: read io port 0x%x\n",port);
870             
871
872     spin_lock_irqsave(&(dev->lock),f);
873     
874     if (palacios_host_dev_rendezvous(dev)) {
875         spin_unlock_irqrestore(&(dev->lock),f);
876         ERROR("palacios: ignoring request as user side is not connected (and did not rendezvous) for host device \"%s\"\n",dev->url);
877         return 0;
878     }
879
880     if (dev->waiting) { 
881         spin_unlock_irqrestore(&(dev->lock),f);
882         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);
883         return 0;
884     }
885
886     
887     
888     // resize request (no data)
889     if (!palacios_bigenough_reqresp(dev->req,0)) {
890         // not enough room.
891         // we drop the lock, turn on interrupts, resize, and then retry
892         DEEP_DEBUG_PRINT("palacios: request not big enough, dropping lock to resize on device \"%s\"\n",dev->url);
893         
894         spin_unlock_irqrestore(&(dev->lock),f);
895         
896         if (palacios_resize_reqresp(&(dev->req),0,0)) {
897             ERROR("palacios: cannot resize for request on device \"%s\"\n",dev->url);
898             return 0;
899         } else {
900             // reacquire the lock
901             // There shouldn't be a race here since there should not be another
902             // request from palacios until this one finishes
903             spin_lock_irqsave(&(dev->lock),f);
904             DEEP_DEBUG_PRINT("palacios: reacquired lock on device \"%s\"\n",dev->url);
905         }
906     }
907     
908
909     dev->req->type=PALACIOS_HOST_DEV_HOST_REQUEST_READ_IO;
910     dev->req->port=port;
911     dev->req->op_len=len;
912     dev->req->gpa=0;
913     dev->req->conf_addr=0;
914     dev->req->data_len=sizeof(struct palacios_host_dev_host_request_response);
915
916     dev->waiting=1;
917     
918     spin_unlock_irqrestore(&(dev->lock),f);
919
920     // hand over to the user space and wait for it to respond
921     cycle_request_response(dev);
922
923     // We're back!   So now we'll hand the response back to Palacios
924
925     spin_lock_irqsave(&(dev->lock),f);
926
927     op_len = dev->resp->op_len < len ? dev->resp->op_len : len ;
928
929     memcpy(dest,dev->resp->data, op_len);
930     
931     spin_unlock_irqrestore(&(dev->lock),f);
932
933     return op_len;
934 }
935
936 static uint64_t palacios_host_dev_read_mem(v3_host_dev_t hostdev,
937                                            void *        gpa,
938                                            void          *dest,
939                                            uint64_t      len)
940 {
941     struct palacios_host_device_user *dev = (struct palacios_host_device_user *)hostdev;
942     unsigned long f;
943     uint64_t op_len;
944
945     DEEP_DEBUG_PRINT("palacios: hostdev: read mem  0x%p\n",gpa);
946
947     spin_lock_irqsave(&(dev->lock),f);
948     
949     if (palacios_host_dev_rendezvous(dev)) {
950         spin_unlock_irqrestore(&(dev->lock),f);
951         ERROR("palacios: ignoring request as user side is not connected (and did not rendezvous) for host device \"%s\"\n",dev->url);
952         return 0;
953     }
954
955     if (dev->waiting) { 
956         spin_unlock_irqrestore(&(dev->lock),f);
957         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);
958         return 0;
959     }
960     
961     // resize request (no data)
962     if (!palacios_bigenough_reqresp(dev->req,0)) {
963         // not enough room.
964         // we drop the lock, turn on interrupts, resize, and then retry
965         DEEP_DEBUG_PRINT("palacios: request not big enough, dropping lock to resize on device \"%s\"\n",dev->url);
966         
967         spin_unlock_irqrestore(&(dev->lock),f);
968         
969         if (palacios_resize_reqresp(&(dev->req),0,0)) {
970             ERROR("palacios: cannot resize for request on device \"%s\"\n",dev->url);
971             return 0;
972         } else {
973             // reacquire the lock
974             // There shouldn't be a race here since there should not be another
975             // request from palacios until this one finishes
976             spin_lock_irqsave(&(dev->lock),f);
977             DEEP_DEBUG_PRINT("palacios: reacquired lock on device \"%s\"\n",dev->url);
978         }
979     }
980
981     dev->req->type=PALACIOS_HOST_DEV_HOST_REQUEST_READ_MEM;
982     dev->req->port=0;
983     dev->req->op_len=len;
984     dev->req->gpa=gpa;
985     dev->req->conf_addr=0;
986     dev->req->data_len=sizeof(struct palacios_host_dev_host_request_response);
987
988     dev->waiting=1;
989     
990     spin_unlock_irqrestore(&(dev->lock),f);
991
992     // hand over to the user space and wait for it to respond
993     cycle_request_response(dev);
994
995     // We're back!   So now we'll hand the response back to Palacios
996
997     spin_lock_irqsave(&(dev->lock),f);
998
999     op_len = dev->resp->op_len < len ? dev->resp->op_len : len ;
1000
1001     memcpy(dest,dev->resp->data, op_len);
1002     
1003     spin_unlock_irqrestore(&(dev->lock),f);
1004
1005     return op_len;
1006 }
1007
1008 static uint64_t palacios_host_dev_read_conf(v3_host_dev_t hostdev,
1009                                             uint64_t      offset,
1010                                             void          *dest,
1011                                             uint64_t      len)
1012 {
1013     struct palacios_host_device_user *dev = (struct palacios_host_device_user *)hostdev;
1014     unsigned long f;
1015     uint64_t op_len;
1016
1017     DEEP_DEBUG_PRINT("palacios: hostdev: read conf 0x%p\n",(void*)offset);
1018
1019     spin_lock_irqsave(&(dev->lock),f);
1020     
1021     if (palacios_host_dev_rendezvous(dev)) {
1022         spin_unlock_irqrestore(&(dev->lock),f);
1023         ERROR("palacios: ignoring request as user side is not connected (and did not rendezvous) for host device \"%s\"\n",dev->url);
1024         return 0;
1025     }
1026
1027     if (dev->waiting) { 
1028         spin_unlock_irqrestore(&(dev->lock),f);
1029         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);
1030         return 0;
1031     }
1032     
1033     // resize request (no data)
1034     if (!palacios_bigenough_reqresp(dev->req,0)) {
1035         // not enough room.
1036         // we drop the lock, turn on interrupts, resize, and then retry
1037         DEEP_DEBUG_PRINT("palacios: request not big enough, dropping lock to resize on device \"%s\"\n",dev->url);
1038         
1039         spin_unlock_irqrestore(&(dev->lock),f);
1040         
1041         if (palacios_resize_reqresp(&(dev->req),0,0)) {
1042             ERROR("palacios: cannot resize for request on device \"%s\"\n",dev->url);
1043             return 0;
1044         } else {
1045             // reacquire the lock
1046             // There shouldn't be a race here since there should not be another
1047             // request from palacios until this one finishes
1048             spin_lock_irqsave(&(dev->lock),f);
1049             DEEP_DEBUG_PRINT("palacios: reacquired lock on device \"%s\"\n",dev->url);
1050         }
1051     }
1052
1053     dev->req->type=PALACIOS_HOST_DEV_HOST_REQUEST_READ_CONF;
1054     dev->req->port=0;
1055     dev->req->op_len=len;
1056     dev->req->gpa=0;
1057     dev->req->conf_addr=offset;
1058     dev->req->data_len=sizeof(struct palacios_host_dev_host_request_response);
1059
1060     dev->waiting=1;
1061     
1062     spin_unlock_irqrestore(&(dev->lock),f);
1063
1064     // hand over to the user space and wait for it to respond
1065     cycle_request_response(dev);
1066
1067     // We're back!   So now we'll hand the response back to Palacios
1068
1069     spin_lock_irqsave(&(dev->lock),f);
1070
1071     op_len = dev->resp->op_len < len ? dev->resp->op_len : len ;
1072
1073     memcpy(dest,dev->resp->data, op_len);
1074     
1075     spin_unlock_irqrestore(&(dev->lock),f);
1076
1077     return op_len;
1078 }
1079
1080
1081 static uint64_t palacios_host_dev_write_io(v3_host_dev_t hostdev,
1082                                            uint16_t      port,
1083                                            void          *src,
1084                                            uint64_t      len)
1085 {
1086     struct palacios_host_device_user *dev = (struct palacios_host_device_user *)hostdev;
1087     unsigned long f;
1088     uint64_t op_len;
1089
1090     DEEP_DEBUG_PRINT("palacios: hostdev: write io port 0x%x \n",port);
1091
1092     spin_lock_irqsave(&(dev->lock),f);
1093     
1094     if (palacios_host_dev_rendezvous(dev)) {
1095         spin_unlock_irqrestore(&(dev->lock),f);
1096         ERROR("palacios: ignoring request as user side is not connected (and did not rendezvous) for host device \"%s\"\n",dev->url);
1097         return 0;
1098     }
1099
1100     if (dev->waiting) { 
1101         spin_unlock_irqrestore(&(dev->lock),f);
1102         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);
1103         return 0;
1104     }
1105
1106     // resize request 
1107     if (!palacios_bigenough_reqresp(dev->req,len)) {
1108         // not enough room.
1109         // we drop the lock, turn on interrupts, resize, and then retry
1110         DEEP_DEBUG_PRINT("palacios: request not big enough, dropping lock to resize on device \"%s\"\n",dev->url);
1111         
1112         spin_unlock_irqrestore(&(dev->lock),f);
1113         
1114         if (palacios_resize_reqresp(&(dev->req),len,0)) {
1115             ERROR("palacios: cannot resize for request on device \"%s\"\n",dev->url);
1116             return 0;
1117         } else {
1118             // reacquire the lock
1119             // There shouldn't be a race here since there should not be another
1120             // request from palacios until this one finishes
1121             spin_lock_irqsave(&(dev->lock),f);
1122             DEEP_DEBUG_PRINT("palacios: reacquired lock on device \"%s\"\n",dev->url);
1123         }
1124     }
1125
1126     dev->req->type=PALACIOS_HOST_DEV_HOST_REQUEST_WRITE_IO;
1127     dev->req->port=port;
1128     dev->req->op_len=len;
1129     dev->req->gpa=0;
1130     dev->req->conf_addr=0;
1131     dev->req->data_len=sizeof(struct palacios_host_dev_host_request_response)+len;
1132
1133     memcpy(dev->req->data,src,len);
1134
1135     dev->waiting=1;
1136
1137     spin_unlock_irqrestore(&(dev->lock),f);
1138    
1139     // hand over to the user space and wait for it to respond
1140     cycle_request_response(dev);
1141
1142     // We're back!   So now we'll hand the response back to Palacios
1143
1144     spin_lock_irqsave(&(dev->lock),f);
1145
1146     op_len = dev->resp->op_len < len ? dev->resp->op_len : len ;
1147
1148     spin_unlock_irqrestore(&(dev->lock),f);
1149
1150     return op_len;
1151 }
1152
1153
1154 static uint64_t palacios_host_dev_write_mem(v3_host_dev_t hostdev,
1155                                             void *        gpa,
1156                                             void          *src,
1157                                             uint64_t      len)
1158 {
1159     struct palacios_host_device_user *dev = (struct palacios_host_device_user *)hostdev;
1160     unsigned long f;
1161     uint64_t op_len;
1162
1163     DEEP_DEBUG_PRINT("palacios: hostdev: write mem 0x%p\n",gpa);
1164
1165     spin_lock_irqsave(&(dev->lock),f);
1166     
1167     if (palacios_host_dev_rendezvous(dev)) {
1168         spin_unlock_irqrestore(&(dev->lock),f);
1169         ERROR("palacios: ignoring request as user side is not connected (and did not rendezvous) for host device \"%s\"\n",dev->url);
1170         return 0;
1171     }
1172
1173     if (dev->waiting) { 
1174         spin_unlock_irqrestore(&(dev->lock),f);
1175         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);
1176         return 0;
1177     }
1178     
1179     // resize request 
1180     if (!palacios_bigenough_reqresp(dev->req,len)) {
1181         // not enough room.
1182         // we drop the lock, turn on interrupts, resize, and then retry
1183         DEEP_DEBUG_PRINT("palacios: request not big enough, dropping lock to resize on device \"%s\"\n",dev->url);
1184         
1185         spin_unlock_irqrestore(&(dev->lock),f);
1186         
1187         if (palacios_resize_reqresp(&(dev->req),len,0)) {
1188             ERROR("palacios: cannot resize for request on device \"%s\"\n",dev->url);
1189             return 0;
1190         } else {
1191             // reacquire the lock
1192             // There shouldn't be a race here since there should not be another
1193             // request from palacios until this one finishes
1194             spin_lock_irqsave(&(dev->lock),f);
1195             DEEP_DEBUG_PRINT("palacios: reacquired lock on device \"%s\"\n",dev->url);
1196         }
1197     }
1198
1199     dev->req->type=PALACIOS_HOST_DEV_HOST_REQUEST_WRITE_MEM;
1200     dev->req->port=0;
1201     dev->req->op_len=len;
1202     dev->req->gpa=gpa;
1203     dev->req->conf_addr=0;
1204     dev->req->data_len=sizeof(struct palacios_host_dev_host_request_response)+len;
1205
1206     memcpy(dev->req->data,src,len);
1207
1208     dev->waiting=1;
1209     
1210     spin_unlock_irqrestore(&(dev->lock),f);
1211
1212     // hand over to the user space and wait for it to respond
1213     cycle_request_response(dev);
1214
1215     // We're back!   So now we'll hand the response back to Palacios
1216
1217     spin_lock_irqsave(&(dev->lock),f);
1218
1219     op_len= dev->resp->op_len < len ? dev->resp->op_len : len ;
1220
1221     spin_unlock_irqrestore(&(dev->lock),f);
1222
1223     return op_len;
1224 }
1225
1226
1227
1228
1229 static uint64_t palacios_host_dev_write_conf(v3_host_dev_t hostdev,
1230                                              uint64_t      offset,
1231                                              void          *src,
1232                                              uint64_t      len)
1233 {
1234     struct palacios_host_device_user *dev = (struct palacios_host_device_user *)hostdev;
1235     unsigned long f;
1236     uint64_t op_len;
1237
1238     DEEP_DEBUG_PRINT("palacios: hostdev: write conf 0x%p\n",(void*)offset);
1239
1240     spin_lock_irqsave(&(dev->lock),f);
1241     
1242     if (palacios_host_dev_rendezvous(dev)) {
1243         spin_unlock_irqrestore(&(dev->lock),f);
1244         ERROR("palacios: ignoring request as user side is not connected (and did not rendezvous) for host device \"%s\"\n",dev->url);
1245         return 0;
1246     }
1247
1248     if (dev->waiting) { 
1249         spin_unlock_irqrestore(&(dev->lock),f);
1250         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);
1251         return 0;
1252     }
1253     
1254     // resize request 
1255     if (!palacios_bigenough_reqresp(dev->req,len)) {
1256         // not enough room.
1257         // we drop the lock, turn on interrupts, resize, and then retry
1258         DEEP_DEBUG_PRINT("palacios: request not big enough, dropping lock to resize on device \"%s\"\n",dev->url);
1259         
1260         spin_unlock_irqrestore(&(dev->lock),f);
1261         
1262         if (palacios_resize_reqresp(&(dev->req),len,0)) {
1263             ERROR("palacios: cannot resize for request on device \"%s\"\n",dev->url);
1264             return 0;
1265         } else {
1266             // reacquire the lock
1267             // There shouldn't be a race here since there should not be another
1268             // request from palacios until this one finishes
1269             spin_lock_irqsave(&(dev->lock),f);
1270             DEEP_DEBUG_PRINT("palacios: reacquired lock on device \"%s\"\n",dev->url);
1271         }
1272     }
1273
1274     dev->req->type=PALACIOS_HOST_DEV_HOST_REQUEST_WRITE_CONF;
1275     dev->req->port=0;
1276     dev->req->op_len=len;
1277     dev->req->gpa=0;
1278     dev->req->conf_addr=offset;
1279     dev->req->data_len=sizeof(struct palacios_host_dev_host_request_response)+len;
1280
1281     memcpy(dev->req->data,src,len);
1282
1283     dev->waiting=1;
1284     
1285     spin_unlock_irqrestore(&(dev->lock),f);
1286
1287     // hand over to the user space and wait for it to respond
1288     cycle_request_response(dev);
1289
1290     // We're back!   So now we'll hand the response back to Palacios
1291
1292     spin_lock_irqsave(&(dev->lock),f);
1293
1294     op_len = dev->resp->op_len < len ? dev->resp->op_len : len ;
1295
1296     spin_unlock_irqrestore(&(dev->lock),f);
1297
1298     return op_len;
1299 }
1300  
1301  
1302 static int palacios_host_dev_ack_irq(v3_host_dev_t hostdev, uint8_t irq)
1303 {
1304     // we don't care
1305     return 0;
1306 }
1307  
1308
1309
1310
1311
1312 static struct v3_host_dev_hooks palacios_host_dev_hooks = {
1313     .open                       = palacios_host_dev_open_deferred,
1314     .close                      = palacios_host_dev_close,
1315     .read_io                    = palacios_host_dev_read_io,
1316     .write_io                   = palacios_host_dev_write_io,
1317     .read_mem                   = palacios_host_dev_read_mem,
1318     .write_mem                  = palacios_host_dev_write_mem,
1319     .read_config                = palacios_host_dev_read_conf,
1320     .write_config               = palacios_host_dev_write_conf,
1321     .ack_irq                    = palacios_host_dev_ack_irq,
1322 };
1323
1324
1325
1326 static int host_dev_init( void ) {
1327     V3_Init_Host_Device_Support(&palacios_host_dev_hooks);
1328     
1329     return 0;
1330 }
1331
1332
1333 static int host_dev_guest_init(struct v3_guest * guest, void ** vm_data ) {
1334     struct palacios_host_dev * host_dev = kmalloc(sizeof(struct palacios_host_dev), GFP_KERNEL);
1335
1336     if (!host_dev) { 
1337         ERROR("palacios: failed to do guest_init for host device\n");
1338         return -1;
1339     }
1340     
1341     
1342     INIT_LIST_HEAD(&(host_dev->devs));
1343     spin_lock_init(&(host_dev->lock));
1344
1345     *vm_data = host_dev;
1346
1347
1348     add_guest_ctrl(guest, V3_VM_HOST_DEV_CONNECT, host_dev_connect, host_dev);
1349
1350     return 0;
1351 }
1352
1353
1354
1355
1356
1357 static struct linux_ext host_dev_ext = {
1358     .name = "HOST_DEVICE_INTERFACE",
1359     .init = host_dev_init,
1360     .deinit = NULL,
1361     .guest_init = host_dev_guest_init,
1362     .guest_deinit = NULL
1363 };
1364
1365
1366 register_extension(&host_dev_ext);