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.


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