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-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         WARNING("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                     ERROR("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                     ERROR("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                     ERROR("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                     ERROR("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             ERROR("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             ERROR("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             ERROR("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             ERROR("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             ERROR("palacios: cannot allocate key space 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             ERROR("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             ERROR("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                 ERROR("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         ERROR("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         ERROR("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         WARNING("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         ERROR("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         ERROR("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             ERROR("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                 ERROR("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                 ERROR("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                 ERROR("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                 ERROR("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         ERROR("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         ERROR("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         ERROR("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         ERROR("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         ERROR("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         ERROR("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 static long keyed_stream_ioctl_user(struct file * filp, unsigned int ioctl, unsigned long arg)
880 {
881     void __user *argp = (void __user *)arg;
882     unsigned long flags;
883     uint64_t size;
884     
885     struct user_keyed_stream *s = (struct user_keyed_stream *) (filp->private_data);
886     
887     switch (ioctl) {
888
889         case V3_KSTREAM_REQUEST_SIZE_IOCTL:
890             
891             // inform request size
892             
893             spin_lock_irqsave(&(s->lock), flags);
894             
895             if (!(s->waiting)) {
896                 spin_unlock_irqrestore(&(s->lock), flags);
897                 return 0;
898             }
899
900             size =  sizeof(struct palacios_user_keyed_stream_op) + s->op->buf_len;
901             
902             if (copy_to_user((void * __user) argp, &size, sizeof(uint64_t))) {
903                 spin_unlock_irqrestore(&(s->lock), flags);
904                 ERROR("palacios: palacios user key size request failed to copy data\n");
905                 return -EFAULT;
906             }
907             
908             spin_unlock_irqrestore(&(s->lock), flags);
909             
910             return 1;
911             
912             break;
913
914         case V3_KSTREAM_REQUEST_PULL_IOCTL: 
915                 
916             // pull the request
917             
918             spin_lock_irqsave(&(s->lock), flags);
919
920             if (!(s->waiting)) {
921                 spin_unlock_irqrestore(&(s->lock), flags);
922                 ERROR("palacios: palacios user key pull request when not waiting\n");
923                 return 0;
924             }
925
926             size =  sizeof(struct palacios_user_keyed_stream_op) + s->op->buf_len;
927
928
929             if (copy_to_user((void __user *) argp, s->op, size)) {
930                 spin_unlock_irqrestore(&(s->lock), flags);
931                 ERROR("palacios: palacios user key pull request failed to copy data\n");
932                 return -EFAULT;
933             }
934
935             spin_unlock_irqrestore(&(s->lock), flags);
936             
937             return 1;
938             
939          
940             break;
941
942     case V3_KSTREAM_RESPONSE_PUSH_IOCTL:
943
944         // push the response
945
946         spin_lock_irqsave(&(s->lock), flags);
947
948         if (!(s->waiting)) {
949             spin_unlock_irqrestore(&(s->lock), flags);
950             ERROR("palacios: palacios user key push response when not waiting\n");
951             return 0;
952         }
953         
954         if (copy_from_user(&size, (void __user *) argp, sizeof(uint64_t))) {
955             ERROR("palacios: palacios user key push response failed to copy size\n");
956             spin_unlock_irqrestore(&(s->lock), flags);
957             return -EFAULT;
958         }
959
960         if (resize_op(&(s->op),size-sizeof(struct palacios_user_keyed_stream_op))) {
961             ERROR("palacios: unable to resize op in user key push response\n");
962             spin_unlock_irqrestore(&(s->lock), flags);
963             return -EFAULT;
964         }
965
966         if (copy_from_user(s->op, (void __user *) argp, size)) {
967             spin_unlock_irqrestore(&(s->lock), flags);
968             return -EFAULT;
969         }
970
971         do_response_to_request(s,&flags);
972         // this will have unlocked s for us
973
974         return 1;
975
976         break;
977         
978     default:
979         ERROR("palacios: unknown ioctl in user keyed stream\n");
980
981         return -EFAULT;
982
983         break;
984         
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     .compat_ioctl = keyed_stream_ioctl_user,
1011     .unlocked_ioctl = keyed_stream_ioctl_user,
1012     .release = keyed_stream_release_user,
1013 };
1014
1015
1016 /*
1017   user_keyed_streams are allocated on user connect, and deallocated on user release
1018   
1019   palacios-side opens and closes only manipulate the open type
1020 */
1021
1022 int keyed_stream_connect_user(struct v3_guest *guest, unsigned int cmd, unsigned long arg, void *priv_data)
1023 {
1024     int fd;
1025     unsigned long flags;
1026     char *url;
1027     uint64_t len;
1028     struct user_keyed_stream *s;
1029     
1030     if (!user_streams) { 
1031         ERROR("palacios: no user space keyed streams!\n");
1032         return -1;
1033     }
1034
1035     // get the url
1036     if (copy_from_user(&len,(void __user *)arg,sizeof(len))) { 
1037         ERROR("palacios: cannot copy url len from user\n");
1038         return -1;
1039     }
1040
1041     url = kmalloc(len,GFP_KERNEL);
1042     
1043     if (!url) { 
1044         ERROR("palacios: cannot allocate url for user keyed stream\n");
1045         return -1;
1046     }
1047
1048     if (copy_from_user(url,((void __user *)arg)+sizeof(len),len)) {
1049         ERROR("palacios: cannot copy url from user\n");
1050         return -1;
1051     }
1052     url[len-1]=0;
1053         
1054     
1055     // Check for duplicate handler
1056     spin_lock_irqsave(&(user_streams->lock), flags);
1057     list_for_each_entry(s, &(user_streams->streams), node) {
1058         if (!strncasecmp(url, s->url, len)) {
1059             ERROR("palacios: user keyed stream connection with url \"%s\" already exists\n", url);
1060             kfree(url);
1061             return -1;
1062         }
1063     }
1064     spin_unlock_irqrestore(&(user_streams->lock), flags);
1065     
1066     // Create connection
1067     s = kmalloc(sizeof(struct user_keyed_stream), GFP_KERNEL);
1068     
1069     if (!s) {
1070         ERROR("palacios: cannot allocate new user keyed stream for %s\n",url);
1071         kfree(url);
1072         return -1;
1073     }
1074     
1075     
1076     // Get file descriptor
1077     fd = anon_inode_getfd("v3-kstream", &user_keyed_stream_fops, s, 0);
1078
1079     if (fd < 0) {
1080         ERROR("palacios: cannot allocate file descriptor for new user keyed stream for %s\n",url);
1081         kfree(s);
1082         kfree(url);
1083         return -1;
1084     }
1085     
1086     memset(s, 0, sizeof(struct user_keyed_stream));
1087     
1088     s->stype=STREAM_USER;
1089     s->url=url;
1090     
1091     init_waitqueue_head(&(s->user_wait_queue));
1092     init_waitqueue_head(&(s->host_wait_queue));
1093     
1094     // Insert connection into list
1095     spin_lock_irqsave(&(user_streams->lock), flags);
1096     list_add(&(s->node), &(user_streams->streams));
1097     spin_unlock_irqrestore(&(user_streams->lock), flags);
1098     
1099     return fd;
1100 }
1101     
1102 static struct user_keyed_stream *keyed_stream_user_find(char *url)
1103 {
1104     unsigned long flags;
1105     struct user_keyed_stream *s;
1106     
1107     if (!user_streams) { 
1108         ERROR("palacios: no user space keyed streams available\n");
1109         return NULL;
1110     }
1111     
1112     spin_lock_irqsave(&(user_streams->lock), flags);
1113     list_for_each_entry(s, &(user_streams->streams), node) {
1114         if (!strcasecmp(url, s->url)) {
1115             spin_unlock_irqrestore(&(user_streams->lock), flags);
1116             return s;
1117         }
1118     }
1119     
1120     spin_unlock_irqrestore(&(user_streams->lock), flags);
1121     
1122     return NULL;
1123 }
1124     
1125     
1126 static v3_keyed_stream_t open_stream_user(char *url, v3_keyed_stream_open_t ot)
1127 {
1128     unsigned long flags;
1129     struct user_keyed_stream *s;
1130     
1131     s = keyed_stream_user_find(url);
1132     
1133     if (!s) {
1134         ERROR("palacios: cannot open user stream %s as it does not exist yet\n",url);
1135         return NULL;
1136     }
1137
1138     spin_lock_irqsave(&(s->lock), flags);
1139
1140     if (s->waiting) {
1141         spin_unlock_irqrestore(&(s->lock), flags);
1142         ERROR("palacios: cannot open user stream %s as it is already in waiting state\n",url);
1143         return NULL;
1144     }
1145     
1146     s->otype = ot==V3_KS_WR_ONLY_CREATE ? V3_KS_WR_ONLY : ot;
1147     
1148     spin_unlock_irqrestore(&(s->lock), flags);
1149     
1150     return s;
1151     
1152 }
1153     
1154 // close stream does not do anything.  Creation of the stream and its cleanup
1155 // are driven by the user side, not the palacios side
1156 // might eventually want to reference count this, though
1157 static void close_stream_user(v3_keyed_stream_t stream)
1158 {
1159     return;
1160 }
1161
1162 static void preallocate_hint_key_user(v3_keyed_stream_t stream,
1163                                       char *key,
1164                                       uint64_t size)
1165 {
1166     return;
1167 }
1168
1169
1170
1171
1172 static v3_keyed_stream_key_t open_key_user(v3_keyed_stream_t stream, char *key)
1173 {
1174     unsigned long flags;
1175     struct user_keyed_stream *s = (struct user_keyed_stream *) stream;
1176     uint64_t   len = strlen(key)+1;
1177     void *user_key;
1178
1179     spin_lock_irqsave(&(s->lock), flags);
1180
1181
1182     if (resize_op(&(s->op),len)) {
1183         spin_unlock_irqrestore(&(s->lock),flags);
1184         ERROR("palacios: cannot resize op in opening key %s on user keyed stream %s\n",key,s->url);
1185         return NULL;
1186     }
1187
1188     s->op->type = PALACIOS_KSTREAM_OPEN_KEY;
1189     s->op->buf_len = len;
1190     strncpy(s->op->buf,key,len);
1191
1192     // enter with it locked
1193     if (do_request_to_response(s,&flags)) { 
1194         spin_unlock_irqrestore(&(s->lock),flags);
1195         ERROR("palacios: request/response handling failed\n");
1196         return NULL;
1197     }
1198     // return with it locked
1199
1200     user_key=s->op->user_key;
1201
1202     spin_unlock_irqrestore(&(s->lock),flags);
1203
1204     return user_key;
1205 }
1206
1207 static void close_key_user(v3_keyed_stream_t stream, v3_keyed_stream_key_t key)
1208 {
1209     struct user_keyed_stream *s = (struct user_keyed_stream *) stream;
1210     uint64_t   len = 0;
1211     unsigned long flags;
1212     
1213     spin_lock_irqsave(&(s->lock), flags);
1214
1215     if (resize_op(&(s->op),len)) {
1216         spin_unlock_irqrestore(&(s->lock),flags);
1217         ERROR("palacios: cannot resize op in closing key 0x%p on user keyed stream %s\n",key,s->url);
1218         return;
1219     }
1220
1221     s->op->type = PALACIOS_KSTREAM_CLOSE_KEY;
1222     s->op->buf_len = len;
1223     s->op->user_key = key;
1224
1225     // enter with it locked
1226     if (do_request_to_response(s,&flags)) { 
1227         spin_unlock_irqrestore(&(s->lock),flags);
1228         ERROR("palacios: request/response handling failed\n");
1229         return;
1230     }
1231     // return with it locked
1232
1233     spin_unlock_irqrestore(&(s->lock),flags);
1234
1235     return;
1236 }
1237
1238
1239
1240 static sint64_t read_key_user(v3_keyed_stream_t stream, v3_keyed_stream_key_t key,
1241                               void *buf, sint64_t rlen)
1242 {
1243
1244     struct user_keyed_stream *s = (struct user_keyed_stream *) stream;
1245     uint64_t   len = 0 ;
1246     sint64_t   xfer;
1247     unsigned long flags;
1248
1249     spin_lock_irqsave(&(s->lock), flags);
1250
1251     if (s->otype != V3_KS_RD_ONLY) { 
1252         spin_unlock_irqrestore(&(s->lock),flags);
1253         ERROR("palacios: attempt to read key from stream that is not in read state on %s\n",s->url);
1254     }   
1255
1256     if (resize_op(&(s->op),len)) {
1257         spin_unlock_irqrestore(&(s->lock),flags);
1258         ERROR("palacios: cannot resize op in reading key 0x%p on user keyed stream %s\n",key,s->url);
1259         return -1;
1260     }
1261
1262     s->op->type = PALACIOS_KSTREAM_READ_KEY;
1263     s->op->buf_len = len ;
1264     s->op->xfer = rlen;
1265     s->op->user_key = key;
1266
1267     // enter with it locked
1268     if (do_request_to_response(s,&flags)) { 
1269         spin_unlock_irqrestore(&(s->lock),flags);
1270         ERROR("palacios: request/response handling failed\n");
1271         return -1;
1272     }
1273     // return with it locked
1274
1275
1276     if (s->op->xfer>0) { 
1277         memcpy(buf,s->op->buf,s->op->xfer);
1278     }
1279
1280     xfer=s->op->xfer;
1281
1282     spin_unlock_irqrestore(&(s->lock),flags);
1283
1284     return xfer;
1285 }
1286
1287
1288 static sint64_t write_key_user(v3_keyed_stream_t stream, v3_keyed_stream_key_t key,
1289                                void *buf, sint64_t wlen)
1290 {
1291
1292     struct user_keyed_stream *s = (struct user_keyed_stream *) stream;
1293     struct palacios_user_keyed_stream_op *op;
1294     uint64_t   len = wlen ;
1295     sint64_t   xfer;
1296     unsigned long flags;
1297     
1298     spin_lock_irqsave(&(s->lock), flags);
1299
1300     if (s->otype != V3_KS_WR_ONLY) { 
1301         spin_unlock_irqrestore(&(s->lock),flags);
1302         ERROR("palacios: attempt to write key on stream that is not in write state on %s\n",s->url);
1303     }   
1304
1305     if (resize_op(&(s->op),len)) {
1306         spin_unlock_irqrestore(&(s->lock),flags);
1307         ERROR("palacios: cannot resize op in reading key 0x%p on user keyed stream %s\n",key,s->url);
1308         return -1;
1309     }
1310
1311     op = s->op;
1312
1313     s->op->type = PALACIOS_KSTREAM_WRITE_KEY;
1314     s->op->buf_len = len;
1315     s->op->xfer = wlen;
1316     s->op->user_key = key;
1317
1318     memcpy(s->op->buf,buf,wlen);
1319
1320     // enter with it locked
1321     if (do_request_to_response(s,&flags)) { 
1322         spin_unlock_irqrestore(&(s->lock),flags);
1323         ERROR("palacios: request/response handling failed\n");
1324         return -1;
1325     }
1326     // return with it locked
1327
1328     xfer=s->op->xfer;
1329
1330     spin_unlock_irqrestore(&(s->lock),flags);
1331
1332     return xfer;
1333 }
1334
1335
1336
1337
1338 /***************************************************************************************************
1339   Generic interface
1340 *************************************************************************************************/
1341
1342 static v3_keyed_stream_t open_stream(char *url,
1343                                      v3_keyed_stream_open_t ot)
1344 {
1345     if (!strncasecmp(url,"mem:",4)) { 
1346         return open_stream_mem(url,ot);
1347     } else if (!strncasecmp(url,"file:",5)) { 
1348         return open_stream_file(url,ot);
1349     } else if (!strncasecmp(url,"user:",5)) { 
1350         return open_stream_user(url,ot);
1351     } else {
1352         ERROR("palacios: unsupported type in attempt to open keyed stream \"%s\"\n",url);
1353         return 0;
1354     }
1355 }
1356
1357 static void close_stream(v3_keyed_stream_t stream)
1358 {
1359     struct generic_keyed_stream *gks = (struct generic_keyed_stream *) stream;
1360     switch (gks->stype){ 
1361         case STREAM_MEM:
1362             return close_stream_mem(stream);
1363             break;
1364         case STREAM_FILE:
1365             return close_stream_file(stream);
1366             break;
1367         case STREAM_USER:
1368             return close_stream_user(stream);
1369             break;
1370         default:
1371             ERROR("palacios: unknown stream type %d in close\n",gks->stype);
1372             break;
1373     }
1374 }
1375
1376 static void preallocate_hint_key(v3_keyed_stream_t stream,
1377                                  char *key,
1378                                  uint64_t size)
1379 {
1380     struct generic_keyed_stream *gks = (struct generic_keyed_stream *) stream;
1381     switch (gks->stype){ 
1382         case STREAM_MEM:
1383             preallocate_hint_key_mem(stream,key,size);
1384             break;
1385         case STREAM_FILE:
1386             preallocate_hint_key_file(stream,key,size);
1387             break;
1388         case STREAM_USER:
1389             return preallocate_hint_key_user(stream,key,size);
1390             break;
1391         default:
1392             ERROR("palacios: unknown stream type %d in preallocate_hint_key\n",gks->stype);
1393             break;
1394     }
1395     return;
1396 }
1397
1398
1399 static v3_keyed_stream_key_t open_key(v3_keyed_stream_t stream,
1400                                       char *key)
1401 {
1402     struct generic_keyed_stream *gks = (struct generic_keyed_stream *) stream;
1403     switch (gks->stype){ 
1404         case STREAM_MEM:
1405             return open_key_mem(stream,key);
1406             break;
1407         case STREAM_FILE:
1408             return open_key_file(stream,key);
1409             break;
1410         case STREAM_USER:
1411             return open_key_user(stream,key);
1412             break;
1413         default:
1414             ERROR("palacios: unknown stream type %d in open_key\n",gks->stype);
1415             break;
1416     }
1417     return 0;
1418 }
1419
1420
1421 static void close_key(v3_keyed_stream_t stream, 
1422                       v3_keyed_stream_key_t key)
1423 {
1424     struct generic_keyed_stream *gks = (struct generic_keyed_stream *) stream;
1425     switch (gks->stype){ 
1426         case STREAM_MEM:
1427             return close_key_mem(stream,key);
1428             break;
1429         case STREAM_FILE:
1430             return close_key_file(stream,key);
1431             break;
1432         case STREAM_USER:
1433             return close_key_user(stream,key);
1434             break;
1435         default:
1436             ERROR("palacios: unknown stream type %d in close_key\n",gks->stype);
1437             break;
1438     }
1439     // nothing to do
1440     return;
1441 }
1442
1443 static sint64_t write_key(v3_keyed_stream_t stream, 
1444                           v3_keyed_stream_key_t key,
1445                           void *buf,
1446                           sint64_t len)
1447 {
1448     struct generic_keyed_stream *gks = (struct generic_keyed_stream *) stream;
1449     switch (gks->stype){ 
1450         case STREAM_MEM:
1451             return write_key_mem(stream,key,buf,len);
1452             break;
1453         case STREAM_FILE:
1454             return write_key_file(stream,key,buf,len);
1455             break;
1456         case STREAM_USER:
1457             return write_key_user(stream,key,buf,len);
1458             break;
1459         default:
1460             ERROR("palacios: unknown stream type %d in write_key\n",gks->stype);
1461             return -1;
1462             break;
1463     }
1464     return -1;
1465 }
1466
1467
1468 static sint64_t read_key(v3_keyed_stream_t stream, 
1469                          v3_keyed_stream_key_t key,
1470                          void *buf,
1471                          sint64_t len)
1472 {
1473     struct generic_keyed_stream *gks = (struct generic_keyed_stream *) stream;
1474     switch (gks->stype){ 
1475         case STREAM_MEM:
1476             return read_key_mem(stream,key,buf,len);
1477             break;
1478         case STREAM_FILE:
1479             return read_key_file(stream,key,buf,len);
1480             break;
1481         case STREAM_USER:
1482             return read_key_user(stream,key,buf,len);
1483             break;
1484         default:
1485             ERROR("palacios: unknown stream type %d in read_key\n",gks->stype);
1486             return -1;
1487             break;
1488     }
1489     return -1;
1490 }
1491
1492
1493
1494
1495 /***************************************************************************************************
1496   Hooks to palacios and inititialization
1497 *************************************************************************************************/
1498
1499     
1500 static struct v3_keyed_stream_hooks hooks = {
1501     .open = open_stream,
1502     .close = close_stream,
1503     .preallocate_hint_key = preallocate_hint_key,
1504     .open_key = open_key,
1505     .close_key = close_key,
1506     .read_key = read_key,
1507     .write_key = write_key
1508 };
1509
1510
1511 static int init_keyed_streams( void )
1512 {
1513     mem_streams = palacios_create_htable(DEF_NUM_STREAMS,hash_func,hash_comp);
1514
1515     if (!mem_streams) { 
1516         ERROR("palacios: failed to allocated stream pool for in-memory streams\n");
1517         return -1;
1518     }
1519
1520     user_streams = kmalloc(sizeof(struct user_keyed_streams),GFP_KERNEL);
1521
1522     if (!user_streams) { 
1523         ERROR("palacios: failed to allocated list for user streams\n");
1524         return -1;
1525     }
1526
1527     INIT_LIST_HEAD(&(user_streams->streams));
1528     
1529     spin_lock_init(&(user_streams->lock));
1530
1531     V3_Init_Keyed_Streams(&hooks);
1532
1533     return 0;
1534
1535 }
1536
1537 static int deinit_keyed_streams( void )
1538 {
1539     palacios_free_htable(mem_streams,1,1);
1540
1541     kfree(user_streams);
1542
1543     WARNING("Deinit of Palacios Keyed Streams likely leaked memory\n");
1544
1545     return 0;
1546 }
1547
1548
1549 static int guest_init_keyed_streams(struct v3_guest * guest, void ** vm_data ) 
1550 {
1551     
1552     add_guest_ctrl(guest, V3_VM_KSTREAM_USER_CONNECT, keyed_stream_connect_user, 0);
1553     
1554     return 0;
1555 }
1556
1557
1558 static int guest_deinit_keyed_streams(struct v3_guest * guest, void * vm_data)
1559 {
1560
1561     return 0;
1562 }
1563
1564
1565
1566
1567 static struct linux_ext key_stream_ext = {
1568     .name = "KEYED_STREAM_INTERFACE",
1569     .init = init_keyed_streams,
1570     .deinit = deinit_keyed_streams,
1571     .guest_init = guest_init_keyed_streams,
1572     .guest_deinit = guest_deinit_keyed_streams, 
1573 };
1574
1575
1576 register_extension(&key_stream_ext);