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.


fc0e1b9c4b32f5eee68ad59e35f8c0a43b9ea78b
[palacios.git] / linux_module / iface-keyed-stream.c
1 /*
2  * Palacios keyed stream interface
3  *
4  * Plus implementations for mem, file, and user space implementations
5  *
6  * (c) Peter Dinda, 2011 (interface, mem + file implementations + recooked user impl)
7  * (c) Clint Sbisa, 2011 (initial user space implementation on which this is based)
8  */
9
10 #include <linux/fs.h>
11 #include <linux/file.h>
12 #include <linux/uaccess.h>
13 #include <linux/namei.h>
14 #include <linux/vmalloc.h>
15 #include <linux/poll.h>
16 #include <linux/anon_inodes.h>
17
18 #include "palacios.h"
19 #include "util-hashtable.h"
20 #include "linux-exts.h"
21 #include "vm.h"
22
23 #define sint64_t int64_t
24 #include <interfaces/vmm_keyed_stream.h>
25
26 #include "iface-keyed-stream-user.h"
27
28 /*
29   This is an implementation of the Palacios keyed stream interface
30   that supports three flavors of streams:
31
32   "mem:"   Streams are stored in a hash table
33   The values for this hash table are hash tables associated with 
34   each stream.   
35
36   "file:"  Streams are stored in files.  Each high-level
37   open corresponds to a directory, while  key corresponds to
38   a distinct file in that directory. 
39
40   "user:" Stream requests are bounced to user space to be 
41    handled there.  A rendezvous approach similar to the host 
42    device userland support is used
43    
44 */
45
46 #define STREAM_GENERIC 0
47 #define STREAM_MEM     1
48 #define STREAM_FILE    2
49 #define STREAM_USER    3
50
51 /*
52   All keyed streams and streams indicate their implementation type within the first field
53  */
54 struct generic_keyed_stream {
55     int stype;
56 };
57
58 struct generic_stream {
59     int stype;
60 };
61   
62
63
64
65 /****************************************************************************************
66    Memory-based implementation  ("mem:")
67 ****************************************************************************************/
68
69 #define DEF_NUM_STREAMS 16
70 #define DEF_NUM_KEYS    128
71 #define DEF_SIZE        128
72
73 /*
74   A memory keyed stream is a pointer to the underlying hash table
75   while a memory stream contains an extensible buffer for the stream
76  */
77 struct mem_keyed_stream {
78     int stype;
79     v3_keyed_stream_open_t ot;
80     struct hashtable *ht;
81 };
82
83 struct mem_stream {
84     int       stype;
85     char     *data;
86     uint32_t  size;
87     uint32_t  data_max;
88     uint32_t  ptr;
89 };
90
91 static struct mem_stream *create_mem_stream_internal(uint64_t size)
92 {
93     struct mem_stream *m = kmalloc(sizeof(struct mem_stream),GFP_KERNEL);
94
95     if (!m) {
96         return 0;
97     }
98
99
100     m->data = vmalloc(size);
101     
102     if (!m->data) { 
103         kfree(m);
104         return 0;
105     }
106
107     m->stype = STREAM_MEM;
108     m->size=size;
109     m->ptr=0;
110     m->data_max=0;
111     
112     return m;
113 }
114
115
116 static struct mem_stream *create_mem_stream(void)
117 {
118     return create_mem_stream_internal(DEF_SIZE);
119 }
120
121 static void destroy_mem_stream(struct mem_stream *m)
122 {
123     if (m) {
124         if (m->data) {
125             kfree(m->data);
126         }
127         m->data=0;
128         kfree(m);
129     }
130 }
131     
132 static int expand_mem_stream(struct mem_stream *m, uint32_t new_size)
133 {
134     void *data = vmalloc(new_size);
135     uint32_t nc;
136
137     if (!data) { 
138         return -1;
139     }
140     
141     nc = (new_size<m->data_max) ? new_size : m->data_max;
142
143     memcpy(data,m->data,nc);
144
145     kfree(m->data);
146
147     m->data=data;
148     m->size=new_size;
149     if (m->size<m->data_max) { 
150         m->data_max=m->size;
151     }
152    
153     return 0;
154 }
155
156 static uint32_t write_mem_stream(struct mem_stream *m,
157                                  void *data,
158                                  uint32_t len)
159 {
160     if ((m->ptr + len) > m->size) { 
161         if (expand_mem_stream(m,m->ptr + len)) { 
162             return 0;
163         }
164     }
165     memcpy(m->data+m->ptr,data,len);
166     m->ptr+=len;
167     m->data_max=m->ptr;
168     
169     return len;
170
171 }
172
173 static uint32_t read_mem_stream(struct mem_stream *m,
174                                 void *data,
175                                 uint32_t len)
176 {
177     if ((m->ptr + len) > m->data_max) { 
178         return 0;
179     }
180     memcpy(data,m->data+m->ptr,len);
181     m->ptr+=len;
182     
183     return len;
184
185 }
186
187
188 static void reset_mem_stream(struct mem_stream *m)
189 {
190     m->ptr=0;
191 }
192
193
194 static inline uint_t hash_func(addr_t key)
195 {
196     return palacios_hash_buffer((uchar_t*)key,strlen((uchar_t*)key));
197 }
198
199 static inline int hash_comp(addr_t k1, addr_t k2)
200 {
201     return strcasecmp((char*)k1,(char*)k2)==0;
202 }
203
204
205 // This stores all the memory keyed streams streams
206 static struct hashtable *mem_streams=0;
207
208
209 static v3_keyed_stream_t open_stream_mem(char *url,
210                                          v3_keyed_stream_open_t ot)
211 {
212
213     if (strncasecmp(url,"mem:",4)) { 
214         printk("palacios: illegitimate attempt to open memory stream \"%s\"\n",url);
215         return 0;
216     }
217
218     switch (ot) { 
219         case V3_KS_RD_ONLY:
220         case V3_KS_WR_ONLY: {
221             struct mem_keyed_stream *mks = (struct mem_keyed_stream *) palacios_htable_search(mem_streams,(addr_t)(url+4));
222             if (mks) { 
223                 mks->ot=ot;
224             }
225             return (v3_keyed_stream_t) mks;
226         }
227             break;
228
229         case V3_KS_WR_ONLY_CREATE: {
230             struct mem_keyed_stream *mks = (struct mem_keyed_stream *) palacios_htable_search(mem_streams,(addr_t)(url+4));
231             if (!mks) { 
232                 char *mykey;
233
234                 mykey = kmalloc(strlen(url+4)+1,GFP_KERNEL);
235
236                 if (!mykey) { 
237                     printk("palacios: cannot allocate space for new in-memory keyed stream %s\n",url);
238                     return 0;
239                 }
240
241                 strcpy(mykey,url+4);
242                 
243                 mks = (struct mem_keyed_stream *) kmalloc(sizeof(struct mem_keyed_stream),GFP_KERNEL);
244
245                 if (!mks) { 
246                     kfree(mykey);
247                     printk("palacios: cannot allocate in-memory keyed stream %s\n",url);
248                     return 0;
249                 }
250             
251                 mks->ht = (void*) palacios_create_htable(DEF_NUM_KEYS,hash_func,hash_comp);
252                 if (!mks->ht) { 
253                     kfree(mks);
254                     kfree(mykey);
255                     printk("palacios: cannot allocate in-memory keyed stream %s\n",url);
256                     return 0;
257                 }
258
259                 
260                 if (!palacios_htable_insert(mem_streams,(addr_t)(mykey),(addr_t)mks)) { 
261                     palacios_free_htable(mks->ht,1,1);
262                     kfree(mks);
263                     kfree(mykey);
264                     printk("palacios: cannot insert in-memory keyed stream %s\n",url);
265                     return 0;
266                 }
267                 mks->stype=STREAM_MEM;
268             }
269
270             mks->ot=V3_KS_WR_ONLY;
271             
272             return mks;
273             
274         }
275             break;
276
277         default:
278             printk("palacios: unsupported open type in open_stream_mem\n");
279             break;
280     }
281     
282     return 0;
283         
284 }
285
286
287
288 static void close_stream_mem(v3_keyed_stream_t stream)
289 {
290     // nothing to do
291     return;
292 }
293
294
295 static v3_keyed_stream_key_t open_key_mem(v3_keyed_stream_t stream,
296                                           char *key)
297 {
298     struct mem_keyed_stream *mks = (struct mem_keyed_stream *) stream;
299     struct hashtable *s = mks->ht;
300
301     struct mem_stream *m;
302
303     m = (struct mem_stream *) palacios_htable_search(s,(addr_t)key);
304
305     if (!m) { 
306         char *mykey = kmalloc(strlen(key)+1,GFP_KERNEL);
307
308         if (!mykey) { 
309             printk("palacios: cannot allocate copy of key for key %s\n",key);
310             return 0;
311         }
312
313         strcpy(mykey,key);
314
315         m = create_mem_stream();
316         
317         if (!m) { 
318             kfree(mykey);
319             printk("palacios: cannot allocate mem keyed stream for key %s\n",key);
320             return 0;
321         }
322
323         if (!palacios_htable_insert(s,(addr_t)mykey,(addr_t)m)) {
324             destroy_mem_stream(m);
325             kfree(mykey);
326             printk("palacios: cannot insert mem keyed stream for key %s\n",key);
327             return 0;
328         }
329     }
330
331     reset_mem_stream(m);
332     return m;
333
334 }
335
336
337 static void preallocate_hint_key_mem(v3_keyed_stream_t stream,
338                                      char *key,
339                                      uint64_t size)
340 {
341     struct mem_keyed_stream *mks = (struct mem_keyed_stream *) stream;
342     struct hashtable *s = mks->ht;
343
344     struct mem_stream *m;
345
346     if (mks->ot != V3_KS_WR_ONLY) { 
347         return;
348     }
349
350     m = (struct mem_stream *) palacios_htable_search(s,(addr_t)key);
351
352     if (!m) {
353         char *mykey;
354         
355         mykey=kmalloc(strlen(key)+1,GFP_KERNEL);
356         
357         if (!mykey) { 
358             printk("palacios: cannot allocate key spce for preallocte for key %s\n",key);
359             return;
360         }
361         
362         strcpy(mykey,key);
363        
364         m = create_mem_stream_internal(size);
365         
366         if (!m) { 
367             printk("palacios: cannot preallocate mem keyed stream for key %s\n",key);
368             return;
369         }
370
371         if (!palacios_htable_insert(s,(addr_t)mykey,(addr_t)m)) {
372             printk("palacios: cannot insert preallocated mem keyed stream for key %s\n",key);
373             destroy_mem_stream(m);
374             return;
375         }
376     } else {
377         if (m->data_max < size) { 
378             if (expand_mem_stream(m,size)) { 
379                 printk("palacios: cannot expand key for preallocation for key %s\n",key);
380                 return;
381             }
382         }
383     }
384
385     return;
386
387 }
388
389 static void close_key_mem(v3_keyed_stream_t stream, 
390                           v3_keyed_stream_key_t key)
391 {
392     // nothing to do
393     return;
394 }
395
396 static sint64_t write_key_mem(v3_keyed_stream_t stream, 
397                               v3_keyed_stream_key_t key,
398                               void *buf,
399                               sint64_t len)
400 {
401     struct mem_keyed_stream *mks = (struct mem_keyed_stream *) stream;
402     struct mem_stream *m = (struct mem_stream *) key;
403     uint32_t mylen;
404     uint32_t writelen;
405
406     if (mks->ot!=V3_KS_WR_ONLY) {
407         return -1;
408     }
409
410     if (len<0) { 
411         return -1;
412     }
413     
414     mylen = (uint32_t) len;
415
416     writelen=write_mem_stream(m,buf,mylen);
417
418     if (writelen!=mylen) { 
419         printk("palacios: failed to write all data for key\n");
420         return -1;
421     } else {
422         return (sint64_t)writelen;
423     }
424 }
425
426 static sint64_t read_key_mem(v3_keyed_stream_t stream, 
427                              v3_keyed_stream_key_t key,
428                              void *buf,
429                              sint64_t len)
430 {
431     struct mem_keyed_stream *mks = (struct mem_keyed_stream *) stream;
432     struct mem_stream *m = (struct mem_stream *) key;
433     uint32_t mylen;
434     uint32_t readlen;
435     
436     if (mks->ot!=V3_KS_RD_ONLY) {
437         return -1;
438     }
439
440     if (len<0) { 
441         return -1;
442     }
443     
444     mylen = (uint32_t) len;
445     
446     readlen=read_mem_stream(m,buf,mylen);
447     
448     if (readlen!=mylen) { 
449         printk("palacios: failed to read all data for key\n");
450         return -1;
451     } else {
452         return (sint64_t)readlen;
453     }
454 }
455
456
457 /***************************************************************************************************
458   File-based implementation  ("file:")
459 *************************************************************************************************/
460
461 /*
462   A file keyed stream contains the fd of the directory
463   and a path
464 */
465
466 struct file_keyed_stream {
467     int   stype;
468     v3_keyed_stream_open_t ot;
469     char  *path;
470 };
471
472 struct file_stream {
473     int   stype;
474     struct file *f;   // the opened file
475 };
476
477
478 static v3_keyed_stream_t open_stream_file(char *url,
479                                           v3_keyed_stream_open_t ot)
480 {
481     struct file_keyed_stream *fks;
482     struct nameidata nd;
483
484     if (strncasecmp(url,"file:",5)) { 
485         printk("palacios: illegitimate attempt to open file stream \"%s\"\n",url);
486         return 0;
487     }
488
489     fks = kmalloc(sizeof(struct file_keyed_stream),GFP_KERNEL);
490     
491     if (!fks) { 
492         printk("palacios: cannot allocate space for file stream\n");
493         return 0;
494     }
495
496     fks->path = (char*)kmalloc(strlen(url+5)+1,GFP_KERNEL);
497     
498     if (!(fks->path)) { 
499         printk("palacios: cannot allocate space for file stream\n");
500         kfree(fks);
501         return 0;
502     }
503     
504     strcpy(fks->path,url+5);
505     
506     fks->stype=STREAM_FILE;
507
508     fks->ot= ot==V3_KS_WR_ONLY_CREATE ? V3_KS_WR_ONLY : ot;
509
510     // Does the directory exist, and can we read/write it?
511    
512     if (path_lookup(fks->path,LOOKUP_DIRECTORY|LOOKUP_FOLLOW,&nd)) { 
513
514         // directory does does not exist.  
515
516         if (ot==V3_KS_RD_ONLY || ot==V3_KS_WR_ONLY) { 
517
518             // we are not being asked to create it
519             printk("palacios: attempt to open %s, which does not exist\n",fks->path);
520             goto fail_out;
521
522         } else {
523
524             // We are being asked to create it
525
526             struct dentry *de;
527             int err;
528
529             // Find its parent
530             if (path_lookup(fks->path,LOOKUP_PARENT|LOOKUP_FOLLOW,&nd)) { 
531                 printk("palacios: attempt to create %s failed because its parent cannot be looked up\n",fks->path);
532                 goto fail_out;
533             }
534
535             // Can we write to the parent?
536
537             if (inode_permission(nd.path.dentry->d_inode, MAY_WRITE | MAY_EXEC)) { 
538                 printk("palacios: attempt to open %s, which has the wrong permissions for directory creation\n",fks->path);
539                 goto fail_out;
540             }
541
542             // OK, we can, so let's create it
543
544             de = lookup_create(&nd,1);
545
546             if (IS_ERR(de)) { 
547                 printk("palacios: cannot allocate dentry\n");
548                 goto fail_out;
549             }
550
551             err = vfs_mkdir(nd.path.dentry->d_inode, de, 0700);
552
553             // lookup_create locks this for us!
554
555             mutex_unlock(&(nd.path.dentry->d_inode->i_mutex));
556
557             if (err) {
558                 printk("palacios: attempt to create %s failed because mkdir failed\n",fks->path);
559                 goto fail_out;
560             }
561
562             // now the directory should exist and have reasonable permissions
563             return (v3_keyed_stream_t) fks;
564         }
565     } 
566
567     
568     // we must be in V3_KS_RD_ONLY or V3_KS_WR_ONLY, 
569     // and the directory exists, so we must check the permissions
570
571     if (inode_permission(nd.path.dentry->d_inode, MAY_EXEC | (ot==V3_KS_RD_ONLY ? MAY_READ : MAY_WRITE))) {
572         printk("palacios: attempt to open %s, which has the wrong permissions\n",fks->path);
573         goto fail_out;
574     } else {
575         return (v3_keyed_stream_t) fks;
576     }
577
578
579  fail_out:
580     kfree(fks->path);
581     kfree(fks);
582     return 0;
583
584 }
585
586 static void close_stream_file(v3_keyed_stream_t stream)
587 {
588     struct file_keyed_stream *fks = (struct file_keyed_stream *) stream;
589     
590     kfree(fks->path);
591     kfree(fks);
592
593 }
594
595 static void preallocate_hint_key_file(v3_keyed_stream_t stream,
596                                       char *key,
597                                       uint64_t size)
598 {
599     return;
600 }
601
602 static v3_keyed_stream_key_t open_key_file(v3_keyed_stream_t stream,
603                                            char *key)
604 {
605     struct file_keyed_stream *fks = (struct file_keyed_stream *) stream;
606     struct file_stream *fs;
607     char *path;
608
609     // the path is the stream's path plus the key name
610     // file:/home/foo + "regext" => "/home/foo/regext"
611     path = (char *) kmalloc(strlen(fks->path)+strlen(key)+2,GFP_KERNEL);
612     if (!path) {                                
613         printk("palacios: cannot allocate file keyed stream for key %s\n",key);
614         return 0;
615     }
616     strcpy(path,fks->path);
617     strcat(path,"/");
618     strcat(path,key);
619     
620     fs = (struct file_stream *) kmalloc(sizeof(struct file_stream *),GFP_KERNEL);
621     
622     if (!fs) { 
623         printk("palacios: cannot allocate file keyed stream for key %s\n",key);
624         kfree(path);
625         return 0;
626     }
627
628     fs->stype=STREAM_FILE;
629
630     fs->f = filp_open(path,O_RDWR|O_CREAT,0600);
631     
632     if (IS_ERR(fs->f)) {
633         printk("palacios: cannot open relevent file \"%s\" for stream \"file:%s\" and key \"%s\"\n",path,fks->path,key);
634         kfree(fs);
635         kfree(path);
636         return 0;
637     }
638
639     kfree(path);
640
641     return fs;
642 }
643
644
645 static void close_key_file(v3_keyed_stream_t stream, 
646                            v3_keyed_stream_key_t key)
647 {
648     struct file_stream *fs = (struct file_stream *) key;
649
650     filp_close(fs->f,NULL);
651
652     kfree(fs);
653 }
654
655 static sint64_t write_key_file(v3_keyed_stream_t stream, 
656                                v3_keyed_stream_key_t key,
657                                void *buf,
658                                sint64_t len)
659 {
660     struct file_keyed_stream *fks = (struct file_keyed_stream *) stream;
661     struct file_stream *fs = (struct file_stream *) key;
662     mm_segment_t old_fs;
663     ssize_t done, left, total;
664     
665     if (fks->ot!=V3_KS_WR_ONLY) { 
666         return -1;
667     }
668     
669     if (len<0) { 
670         return -1;
671     }
672
673     total=len;
674     left=len;
675
676     old_fs = get_fs();
677     set_fs(get_ds());
678
679     while (left>0) {
680         done = fs->f->f_op->write(fs->f, buf+(total-left), left, &(fs->f->f_pos));
681         if (done<=0) {
682             return -1;
683         } else {
684             left -= done;
685         }
686     }
687     set_fs(old_fs);
688
689     return len;
690 }
691
692
693
694 static sint64_t read_key_file(v3_keyed_stream_t stream, 
695                               v3_keyed_stream_key_t key,
696                               void *buf,
697                               sint64_t len)
698 {
699     struct file_keyed_stream *fks = (struct file_keyed_stream *) stream;
700     struct file_stream *fs = (struct file_stream *) key;
701     mm_segment_t old_fs;
702     ssize_t done, left, total;
703     
704     if (fks->ot!=V3_KS_RD_ONLY) { 
705         return -1;
706     }
707
708     if (len<0) { 
709         return -1;
710     }
711
712     total=len;
713     left=len;
714
715     old_fs = get_fs();
716     set_fs(get_ds());
717
718     while (left>0) {
719         done = fs->f->f_op->read(fs->f, buf+(total-left), left, &(fs->f->f_pos));
720         if (done<=0) {
721             return -1;
722         } else {
723             left -= done;
724         }
725     }
726     set_fs(old_fs);
727
728     return len;
729
730 }
731
732
733
734
735 /***************************************************************************************************
736   User implementation   ("user:")
737 *************************************************************************************************/
738
739
740 // List of all user keyed stream connections for the guest
741 struct user_keyed_streams {
742     spinlock_t lock;
743     struct list_head streams;
744 };
745
746
747 // A single keyed stream connection to user space
748 struct user_keyed_stream {
749     int stype;
750     v3_keyed_stream_open_t otype;
751
752     char *url;
753     spinlock_t lock;
754     int waiting;
755
756     wait_queue_head_t user_wait_queue;
757     wait_queue_head_t host_wait_queue;
758
759     struct palacios_user_keyed_stream_op *op;
760
761     struct list_head node;
762 };
763
764
765 //
766 // List of all of the user streams
767 //
768 static struct user_keyed_streams *user_streams;
769
770
771
772 static int resize_op(struct palacios_user_keyed_stream_op **op, uint64_t buf_len)
773 {
774     struct palacios_user_keyed_stream_op *old = *op;
775     struct palacios_user_keyed_stream_op *new;
776     
777     if (!old) {
778         new = kmalloc(sizeof(struct palacios_user_keyed_stream_op)+buf_len,GFP_ATOMIC);
779         if (!new) { 
780             return -1;
781         } else {
782             new->len=sizeof(struct palacios_user_keyed_stream_op)+buf_len;
783             new->buf_len=buf_len;
784             *op=new;
785             return 0;
786         }
787     } else {
788         if ((old->len-sizeof(struct palacios_user_keyed_stream_op)) >= buf_len) { 
789             old->buf_len=buf_len;
790             return 0;
791         } else {
792             kfree(old);
793             *op = 0 ;
794             return resize_op(op,buf_len);
795         }
796     }
797 }
798
799 //
800 // The assumption is that we enter this with the stream locked
801 // and we will return with it locked;  additionally, the op structure
802 // will be overwritten with the response
803 // 
804 static int do_request_to_response(struct user_keyed_stream *s, unsigned long *flags)
805 {
806
807     if (s->waiting) {
808         printk("palacios: user keyed stream request attempted while one is already in progress on %s\n",s->url);
809         return -1;
810     }
811
812     // we are now waiting for a response
813     s->waiting = 1;
814
815     // release the stream
816     spin_unlock_irqrestore(&(s->lock), *flags);
817
818     // wake up anyone waiting on it
819     wake_up_interruptible(&(s->user_wait_queue));
820
821     // wait for someone to give us a response
822     while (wait_event_interruptible(s->host_wait_queue, (s->waiting == 0)) != 0) {}
823
824     // reacquire the lock for our called
825     spin_lock_irqsave(&(s->lock), *flags);
826
827     return 0;
828 }
829
830 //
831 // The assumption is that we enter this with the stream locked
832 // and we will return with it UNlocked
833 // 
834 static int do_response_to_request(struct user_keyed_stream *s, unsigned long *flags)
835 {
836
837     if (!(s->waiting)) {
838         printk("palacios: user keyed stream response while no request is in progress on %s\n",s->url);
839         return -1;
840     }
841
842     // we are now waiting for a request
843     s->waiting = 0;
844
845     // release the stream
846     spin_unlock_irqrestore(&(s->lock), *flags);
847
848     // wake up anyone waiting on it
849     wake_up_interruptible(&(s->host_wait_queue));
850     
851     return 0;
852 }
853
854
855
856 static unsigned int keyed_stream_poll_user(struct file *filp, poll_table *wait)
857 {
858     struct user_keyed_stream *s = (struct user_keyed_stream *) (filp->private_data);
859     unsigned long flags;
860     
861     if (!s) {
862         return POLLERR;
863     }
864     
865     spin_lock_irqsave(&(s->lock), flags);
866
867     if (s->waiting) {
868         spin_unlock_irqrestore(&(s->lock), flags);
869         return POLLIN | POLLRDNORM;
870     }
871
872     poll_wait(filp, &(s->user_wait_queue), wait);
873     
874     spin_unlock_irqrestore(&(s->lock), flags);
875
876     return 0;
877 }
878
879
880 static int keyed_stream_ioctl_user(struct inode *inode, struct file *filp, unsigned int ioctl, unsigned long arg)
881 {
882     void __user *argp = (void __user *)arg;
883     unsigned long flags;
884     uint64_t size;
885     
886     struct user_keyed_stream *s = (struct user_keyed_stream *) (filp->private_data);
887     
888     switch (ioctl) {
889
890         case V3_KSTREAM_REQUEST_SIZE_IOCTL:
891             
892             // inform request size
893             
894             spin_lock_irqsave(&(s->lock), flags);
895             
896             if (!(s->waiting)) {
897                 spin_unlock_irqrestore(&(s->lock), flags);
898                 return 0;
899             }
900
901             size =  sizeof(struct palacios_user_keyed_stream_op) + s->op->buf_len;
902             
903             if (copy_to_user((void * __user) argp, &size, sizeof(uint64_t))) {
904                 spin_unlock_irqrestore(&(s->lock), flags);
905                 printk("palacios: palacios user key size request failed to copy data\n");
906                 return -EFAULT;
907             }
908             
909             spin_unlock_irqrestore(&(s->lock), flags);
910             
911             return 1;
912             
913             break;
914
915         case V3_KSTREAM_REQUEST_PULL_IOCTL: 
916                 
917             // pull the request
918             
919             spin_lock_irqsave(&(s->lock), flags);
920
921             if (!(s->waiting)) {
922                 spin_unlock_irqrestore(&(s->lock), flags);
923                 printk("palacios: palacios user key pull request when not waiting\n");
924                 return 0;
925             }
926
927             size =  sizeof(struct palacios_user_keyed_stream_op) + s->op->buf_len;
928
929
930             if (copy_to_user((void __user *) argp, s->op, size)) {
931                 spin_unlock_irqrestore(&(s->lock), flags);
932                 printk("palacios: palacios user key pull request failed to copy data\n");
933                 return -EFAULT;
934             }
935
936             spin_unlock_irqrestore(&(s->lock), flags);
937             
938             return 1;
939             
940          
941             break;
942
943     case V3_KSTREAM_RESPONSE_PUSH_IOCTL:
944
945         // push the response
946
947         spin_lock_irqsave(&(s->lock), flags);
948
949         if (!(s->waiting)) {
950             spin_unlock_irqrestore(&(s->lock), flags);
951             printk("palacios: palacios user key push response when not waiting\n");
952             return 0;
953         }
954         
955         if (copy_from_user(&size, (void __user *) argp, sizeof(uint64_t))) {
956             printk("palacios: palacios user key push response failed to copy size\n");
957             spin_unlock_irqrestore(&(s->lock), flags);
958             return -EFAULT;
959         }
960
961         if (resize_op(&(s->op),size-sizeof(struct palacios_user_keyed_stream_op))) {
962             printk("palacios: unable to resize op in user key push response\n");
963             spin_unlock_irqrestore(&(s->lock), flags);
964             return -EFAULT;
965         }
966
967         if (copy_from_user(s->op, (void __user *) argp, size)) {
968             spin_unlock_irqrestore(&(s->lock), flags);
969             return -EFAULT;
970         }
971
972         do_response_to_request(s,&flags);
973         // this will have unlocked s for us
974
975         return 1;
976
977         break;
978         
979     default:
980         printk("palacios: unknown ioctl in user keyed stream\n");
981
982         return -EFAULT;
983
984         break;
985         
986     }
987 }
988
989 static int keyed_stream_release_user(struct inode *inode, struct file *filp)
990 {
991     struct user_keyed_stream *s = filp->private_data;
992     unsigned long f1,f2;
993
994     spin_lock_irqsave(&(user_streams->lock),f1);
995     spin_lock_irqsave(&(s->lock), f2);
996
997     list_del(&(s->node));
998
999     spin_unlock_irqrestore(&(s->lock), f2);
1000     spin_unlock_irqrestore(&(user_streams->lock), f1);
1001     
1002     kfree(s->url);
1003     kfree(s);
1004
1005     return 0;
1006 }
1007
1008 static struct file_operations user_keyed_stream_fops = {
1009     .poll = keyed_stream_poll_user,
1010     .ioctl = keyed_stream_ioctl_user,
1011     .release = keyed_stream_release_user,
1012 };
1013
1014
1015 /*
1016   user_keyed_streams are allocated on user connect, and deallocated on user release
1017   
1018   palacios-side opens and closes only manipulate the open type
1019 */
1020
1021 int keyed_stream_connect_user(struct v3_guest *guest, unsigned int cmd, unsigned long arg, void *priv_data)
1022 {
1023     int fd;
1024     unsigned long flags;
1025     char *url;
1026     uint64_t len;
1027     struct user_keyed_stream *s;
1028     
1029     if (!user_streams) { 
1030         printk("palacios: no user space keyed streams!\n");
1031         return -1;
1032     }
1033
1034     // get the url
1035     if (copy_from_user(&len,(void __user *)arg,sizeof(len))) { 
1036         printk("palacios: cannot copy url len from user\n");
1037         return -1;
1038     }
1039
1040     url = kmalloc(len,GFP_KERNEL);
1041     
1042     if (!url) { 
1043         printk("palacios: cannot allocate url for user keyed stream\n");
1044         return -1;
1045     }
1046
1047     if (copy_from_user(url,((void __user *)arg)+sizeof(len),len)) {
1048         printk("palacios: cannot copy url from user\n");
1049         return -1;
1050     }
1051     url[len-1]=0;
1052         
1053     
1054     // Check for duplicate handler
1055     spin_lock_irqsave(&(user_streams->lock), flags);
1056     list_for_each_entry(s, &(user_streams->streams), node) {
1057         if (!strncasecmp(url, s->url, len)) {
1058             printk("palacios: user keyed stream connection with url \"%s\" already exists\n", url);
1059             kfree(url);
1060             return -1;
1061         }
1062     }
1063     spin_unlock_irqrestore(&(user_streams->lock), flags);
1064     
1065     // Create connection
1066     s = kmalloc(sizeof(struct user_keyed_stream), GFP_KERNEL);
1067     
1068     if (!s) {
1069         printk("palacios: cannot allocate new user keyed stream for %s\n",url);
1070         kfree(url);
1071         return -1;
1072     }
1073     
1074     
1075     // Get file descriptor
1076     fd = anon_inode_getfd("v3-kstream", &user_keyed_stream_fops, s, 0);
1077
1078     if (fd < 0) {
1079         printk("palacios: cannot allocate file descriptor for new user keyed stream for %s\n",url);
1080         kfree(s);
1081         kfree(url);
1082         return -1;
1083     }
1084     
1085     memset(s, 0, sizeof(struct user_keyed_stream));
1086     
1087     s->stype=STREAM_USER;
1088     s->url=url;
1089     
1090     init_waitqueue_head(&(s->user_wait_queue));
1091     init_waitqueue_head(&(s->host_wait_queue));
1092     
1093     // Insert connection into list
1094     spin_lock_irqsave(&(user_streams->lock), flags);
1095     list_add(&(s->node), &(user_streams->streams));
1096     spin_unlock_irqrestore(&(user_streams->lock), flags);
1097     
1098     return fd;
1099 }
1100     
1101 static struct user_keyed_stream *keyed_stream_user_find(char *url)
1102 {
1103     unsigned long flags;
1104     struct user_keyed_stream *s;
1105     
1106     if (!user_streams) { 
1107         printk("palacios: no user space keyed streams available\n");
1108         return NULL;
1109     }
1110     
1111     spin_lock_irqsave(&(user_streams->lock), flags);
1112     list_for_each_entry(s, &(user_streams->streams), node) {
1113         if (!strcasecmp(url, s->url)) {
1114             spin_unlock_irqrestore(&(user_streams->lock), flags);
1115             return s;
1116         }
1117     }
1118     
1119     spin_unlock_irqrestore(&(user_streams->lock), flags);
1120     
1121     return NULL;
1122 }
1123     
1124     
1125 static v3_keyed_stream_t open_stream_user(char *url, v3_keyed_stream_open_t ot)
1126 {
1127     unsigned long flags;
1128     struct user_keyed_stream *s;
1129     
1130     s = keyed_stream_user_find(url);
1131     
1132     if (!s) {
1133         printk("palacios: cannot open user stream %s as it does not exist yet\n",url);
1134         return NULL;
1135     }
1136
1137     spin_lock_irqsave(&(s->lock), flags);
1138
1139     if (s->waiting) {
1140         spin_unlock_irqrestore(&(s->lock), flags);
1141         printk("palacios: cannot open user stream %s as it is already in waiting state\n",url);
1142         return NULL;
1143     }
1144     
1145     s->otype = ot==V3_KS_WR_ONLY_CREATE ? V3_KS_WR_ONLY : ot;
1146     
1147     spin_unlock_irqrestore(&(s->lock), flags);
1148     
1149     return s;
1150     
1151 }
1152     
1153 // close stream does not do anything.  Creation of the stream and its cleanup
1154 // are driven by the user side, not the palacios side
1155 // might eventually want to reference count this, though
1156 static void close_stream_user(v3_keyed_stream_t stream)
1157 {
1158     return;
1159 }
1160
1161 static void preallocate_hint_key_user(v3_keyed_stream_t stream,
1162                                       char *key,
1163                                       uint64_t size)
1164 {
1165     return;
1166 }
1167
1168
1169
1170
1171 static v3_keyed_stream_key_t open_key_user(v3_keyed_stream_t stream, char *key)
1172 {
1173     unsigned long flags;
1174     struct user_keyed_stream *s = (struct user_keyed_stream *) stream;
1175     uint64_t   len = strlen(key)+1;
1176     void *user_key;
1177
1178     spin_lock_irqsave(&(s->lock), flags);
1179
1180
1181     if (resize_op(&(s->op),len)) {
1182         spin_unlock_irqrestore(&(s->lock),flags);
1183         printk("palacios: cannot resize op in opening key %s on user keyed stream %s\n",key,s->url);
1184         return NULL;
1185     }
1186
1187     s->op->type = PALACIOS_KSTREAM_OPEN_KEY;
1188     s->op->buf_len = len;
1189     strncpy(s->op->buf,key,len);
1190
1191     // enter with it locked
1192     if (do_request_to_response(s,&flags)) { 
1193         spin_unlock_irqrestore(&(s->lock),flags);
1194         printk("palacios: request/response handling failed\n");
1195         return NULL;
1196     }
1197     // return with it locked
1198
1199     user_key=s->op->user_key;
1200
1201     spin_unlock_irqrestore(&(s->lock),flags);
1202
1203     return user_key;
1204 }
1205
1206 static void close_key_user(v3_keyed_stream_t stream, v3_keyed_stream_key_t key)
1207 {
1208     struct user_keyed_stream *s = (struct user_keyed_stream *) stream;
1209     uint64_t   len = 0;
1210     unsigned long flags;
1211     
1212     spin_lock_irqsave(&(s->lock), flags);
1213
1214     if (resize_op(&(s->op),len)) {
1215         spin_unlock_irqrestore(&(s->lock),flags);
1216         printk("palacios: cannot resize op in closing key 0x%p on user keyed stream %s\n",key,s->url);
1217         return;
1218     }
1219
1220     s->op->type = PALACIOS_KSTREAM_CLOSE_KEY;
1221     s->op->buf_len = len;
1222     s->op->user_key = key;
1223
1224     // enter with it locked
1225     if (do_request_to_response(s,&flags)) { 
1226         spin_unlock_irqrestore(&(s->lock),flags);
1227         printk("palacios: request/response handling failed\n");
1228         return;
1229     }
1230     // return with it locked
1231
1232     spin_unlock_irqrestore(&(s->lock),flags);
1233
1234     return;
1235 }
1236
1237
1238
1239 static sint64_t read_key_user(v3_keyed_stream_t stream, v3_keyed_stream_key_t key,
1240                               void *buf, sint64_t rlen)
1241 {
1242
1243     struct user_keyed_stream *s = (struct user_keyed_stream *) stream;
1244     uint64_t   len = 0 ;
1245     sint64_t   xfer;
1246     unsigned long flags;
1247
1248     spin_lock_irqsave(&(s->lock), flags);
1249
1250     if (s->otype != V3_KS_RD_ONLY) { 
1251         spin_unlock_irqrestore(&(s->lock),flags);
1252         printk("palacios: attempt to read key from stream that is not in read state on %s\n",s->url);
1253     }   
1254
1255     if (resize_op(&(s->op),len)) {
1256         spin_unlock_irqrestore(&(s->lock),flags);
1257         printk("palacios: cannot resize op in reading key 0x%p on user keyed stream %s\n",key,s->url);
1258         return -1;
1259     }
1260
1261     s->op->type = PALACIOS_KSTREAM_READ_KEY;
1262     s->op->buf_len = len ;
1263     s->op->xfer = rlen;
1264     s->op->user_key = key;
1265
1266     // enter with it locked
1267     if (do_request_to_response(s,&flags)) { 
1268         spin_unlock_irqrestore(&(s->lock),flags);
1269         printk("palacios: request/response handling failed\n");
1270         return -1;
1271     }
1272     // return with it locked
1273
1274
1275     if (s->op->xfer>0) { 
1276         memcpy(buf,s->op->buf,s->op->xfer);
1277     }
1278
1279     xfer=s->op->xfer;
1280
1281     spin_unlock_irqrestore(&(s->lock),flags);
1282
1283     return xfer;
1284 }
1285
1286
1287 static sint64_t write_key_user(v3_keyed_stream_t stream, v3_keyed_stream_key_t key,
1288                                void *buf, sint64_t wlen)
1289 {
1290
1291     struct user_keyed_stream *s = (struct user_keyed_stream *) stream;
1292     struct palacios_user_keyed_stream_op *op;
1293     uint64_t   len = wlen ;
1294     sint64_t   xfer;
1295     unsigned long flags;
1296     
1297     spin_lock_irqsave(&(s->lock), flags);
1298
1299     if (s->otype != V3_KS_WR_ONLY) { 
1300         spin_unlock_irqrestore(&(s->lock),flags);
1301         printk("palacios: attempt to write key on stream that is not in write state on %s\n",s->url);
1302     }   
1303
1304     if (resize_op(&(s->op),len)) {
1305         spin_unlock_irqrestore(&(s->lock),flags);
1306         printk("palacios: cannot resize op in reading key 0x%p on user keyed stream %s\n",key,s->url);
1307         return -1;
1308     }
1309
1310     op = s->op;
1311
1312     s->op->type = PALACIOS_KSTREAM_WRITE_KEY;
1313     s->op->buf_len = len;
1314     s->op->xfer = wlen;
1315     s->op->user_key = key;
1316
1317     memcpy(s->op->buf,buf,wlen);
1318
1319     // enter with it locked
1320     if (do_request_to_response(s,&flags)) { 
1321         spin_unlock_irqrestore(&(s->lock),flags);
1322         printk("palacios: request/response handling failed\n");
1323         return -1;
1324     }
1325     // return with it locked
1326
1327     xfer=s->op->xfer;
1328
1329     spin_unlock_irqrestore(&(s->lock),flags);
1330
1331     return xfer;
1332 }
1333
1334
1335
1336
1337 /***************************************************************************************************
1338   Generic interface
1339 *************************************************************************************************/
1340
1341 static v3_keyed_stream_t open_stream(char *url,
1342                                      v3_keyed_stream_open_t ot)
1343 {
1344     if (!strncasecmp(url,"mem:",4)) { 
1345         return open_stream_mem(url,ot);
1346     } else if (!strncasecmp(url,"file:",5)) { 
1347         return open_stream_file(url,ot);
1348     } else if (!strncasecmp(url,"user:",5)) { 
1349         return open_stream_user(url,ot);
1350     } else {
1351         printk("palacios: unsupported type in attempt to open keyed stream \"%s\"\n",url);
1352         return 0;
1353     }
1354 }
1355
1356 static void close_stream(v3_keyed_stream_t stream)
1357 {
1358     struct generic_keyed_stream *gks = (struct generic_keyed_stream *) stream;
1359     switch (gks->stype){ 
1360         case STREAM_MEM:
1361             return close_stream_mem(stream);
1362             break;
1363         case STREAM_FILE:
1364             return close_stream_file(stream);
1365             break;
1366         case STREAM_USER:
1367             return close_stream_user(stream);
1368             break;
1369         default:
1370             printk("palacios: unknown stream type %d in close\n",gks->stype);
1371             break;
1372     }
1373 }
1374
1375 static void preallocate_hint_key(v3_keyed_stream_t stream,
1376                                  char *key,
1377                                  uint64_t size)
1378 {
1379     struct generic_keyed_stream *gks = (struct generic_keyed_stream *) stream;
1380     switch (gks->stype){ 
1381         case STREAM_MEM:
1382             preallocate_hint_key_mem(stream,key,size);
1383             break;
1384         case STREAM_FILE:
1385             preallocate_hint_key_file(stream,key,size);
1386             break;
1387         case STREAM_USER:
1388             return preallocate_hint_key_user(stream,key,size);
1389             break;
1390         default:
1391             printk("palacios: unknown stream type %d in preallocate_hint_key\n",gks->stype);
1392             break;
1393     }
1394     return;
1395 }
1396
1397
1398 static v3_keyed_stream_key_t open_key(v3_keyed_stream_t stream,
1399                                       char *key)
1400 {
1401     struct generic_keyed_stream *gks = (struct generic_keyed_stream *) stream;
1402     switch (gks->stype){ 
1403         case STREAM_MEM:
1404             return open_key_mem(stream,key);
1405             break;
1406         case STREAM_FILE:
1407             return open_key_file(stream,key);
1408             break;
1409         case STREAM_USER:
1410             return open_key_user(stream,key);
1411             break;
1412         default:
1413             printk("palacios: unknown stream type %d in open_key\n",gks->stype);
1414             break;
1415     }
1416     return 0;
1417 }
1418
1419
1420 static void close_key(v3_keyed_stream_t stream, 
1421                       v3_keyed_stream_key_t key)
1422 {
1423     struct generic_keyed_stream *gks = (struct generic_keyed_stream *) stream;
1424     switch (gks->stype){ 
1425         case STREAM_MEM:
1426             return close_key_mem(stream,key);
1427             break;
1428         case STREAM_FILE:
1429             return close_key_file(stream,key);
1430             break;
1431         case STREAM_USER:
1432             return close_key_user(stream,key);
1433             break;
1434         default:
1435             printk("palacios: unknown stream type %d in close_key\n",gks->stype);
1436             break;
1437     }
1438     // nothing to do
1439     return;
1440 }
1441
1442 static sint64_t write_key(v3_keyed_stream_t stream, 
1443                           v3_keyed_stream_key_t key,
1444                           void *buf,
1445                           sint64_t len)
1446 {
1447     struct generic_keyed_stream *gks = (struct generic_keyed_stream *) stream;
1448     switch (gks->stype){ 
1449         case STREAM_MEM:
1450             return write_key_mem(stream,key,buf,len);
1451             break;
1452         case STREAM_FILE:
1453             return write_key_file(stream,key,buf,len);
1454             break;
1455         case STREAM_USER:
1456             return write_key_user(stream,key,buf,len);
1457             break;
1458         default:
1459             printk("palacios: unknown stream type %d in write_key\n",gks->stype);
1460             return -1;
1461             break;
1462     }
1463     return -1;
1464 }
1465
1466
1467 static sint64_t read_key(v3_keyed_stream_t stream, 
1468                          v3_keyed_stream_key_t key,
1469                          void *buf,
1470                          sint64_t len)
1471 {
1472     struct generic_keyed_stream *gks = (struct generic_keyed_stream *) stream;
1473     switch (gks->stype){ 
1474         case STREAM_MEM:
1475             return read_key_mem(stream,key,buf,len);
1476             break;
1477         case STREAM_FILE:
1478             return read_key_file(stream,key,buf,len);
1479             break;
1480         case STREAM_USER:
1481             return read_key_user(stream,key,buf,len);
1482             break;
1483         default:
1484             printk("palacios: unknown stream type %d in read_key\n",gks->stype);
1485             return -1;
1486             break;
1487     }
1488     return -1;
1489 }
1490
1491
1492
1493
1494 /***************************************************************************************************
1495   Hooks to palacios and inititialization
1496 *************************************************************************************************/
1497
1498     
1499 static struct v3_keyed_stream_hooks hooks = {
1500     .open = open_stream,
1501     .close = close_stream,
1502     .preallocate_hint_key = preallocate_hint_key,
1503     .open_key = open_key,
1504     .close_key = close_key,
1505     .read_key = read_key,
1506     .write_key = write_key
1507 };
1508
1509
1510 static int init_keyed_streams( void )
1511 {
1512     mem_streams = palacios_create_htable(DEF_NUM_STREAMS,hash_func,hash_comp);
1513
1514     if (!mem_streams) { 
1515         printk("palacios: failed to allocated stream pool for in-memory streams\n");
1516         return -1;
1517     }
1518
1519     user_streams = kmalloc(sizeof(struct user_keyed_streams),GFP_KERNEL);
1520
1521     if (!user_streams) { 
1522         printk("palacios: failed to allocated list for user streams\n");
1523         return -1;
1524     }
1525
1526     INIT_LIST_HEAD(&(user_streams->streams));
1527     
1528     spin_lock_init(&(user_streams->lock));
1529
1530     V3_Init_Keyed_Streams(&hooks);
1531
1532     return 0;
1533
1534 }
1535
1536 static int deinit_keyed_streams( void )
1537 {
1538     palacios_free_htable(mem_streams,1,1);
1539
1540     kfree(user_streams);
1541
1542     printk("Deinit of Palacios Keyed Streams likely leaked memory\n");
1543
1544     return 0;
1545 }
1546
1547
1548 static int guest_init_keyed_streams(struct v3_guest * guest, void ** vm_data ) 
1549 {
1550     
1551     add_guest_ctrl(guest, V3_VM_KSTREAM_USER_CONNECT, keyed_stream_connect_user, 0);
1552     
1553     return 0;
1554 }
1555
1556
1557 static int guest_deinit_keyed_streams(struct v3_guest * guest, void * vm_data)
1558 {
1559
1560     return 0;
1561 }
1562
1563
1564
1565
1566 static struct linux_ext key_stream_ext = {
1567     .name = "KEYED_STREAM_INTERFACE",
1568     .init = init_keyed_streams,
1569     .deinit = deinit_keyed_streams,
1570     .guest_init = guest_init_keyed_streams,
1571     .guest_deinit = guest_deinit_keyed_streams, 
1572 };
1573
1574
1575 register_extension(&key_stream_ext);