6 #include <linux/errno.h>
7 #include <linux/percpu.h>
8 #include <linux/sched.h>
10 #include <palacios/vmm_stream.h>
11 #include "palacios-stream.h"
13 static struct list_head global_streams;
15 int stream_enqueue(struct stream_buffer * stream, char * buf, int len) {
18 bytes = ringbuf_write(stream->buf, buf, len);
24 int stream_dequeue(struct stream_buffer * stream, char * buf, int len) {
27 bytes = ringbuf_read(stream->buf, buf, len);
32 int stream_datalen(struct stream_buffer * stream){
33 return ringbuf_data_len(stream->buf);
37 struct stream_buffer * find_stream_by_name(struct v3_guest * guest, const char * name) {
38 struct stream_buffer * stream = NULL;
39 struct list_head * stream_list = NULL;
42 stream_list = &global_streams;
44 stream_list = &(guest->streams);
47 list_for_each_entry(stream, stream_list, stream_node) {
48 if (strncmp(stream->name, name, STREAM_NAME_LEN) == 0) {
57 static void * palacios_stream_open(const char * name, void * private_data) {
58 struct v3_guest * guest = (struct v3_guest *)private_data;
59 struct stream_buffer * stream = NULL;
61 if (find_stream_by_name(guest, name) != NULL) {
62 printk("Stream already exists\n");
66 stream = kmalloc(sizeof(struct stream_buffer), GFP_KERNEL);
68 stream->buf = create_ringbuf(STREAM_BUF_SIZE);
69 stream->guest = guest;
71 strncpy(stream->name, name, STREAM_NAME_LEN - 1);
73 init_waitqueue_head(&(stream->intr_queue));
74 spin_lock_init(&(stream->lock));
77 list_add(&(stream->stream_node), &(global_streams));
79 list_add(&(stream->stream_node), &(guest->streams));
86 static int palacios_stream_write(void * stream_ptr, char * buf, int len) {
87 struct stream_buffer * stream = (struct stream_buffer *)stream_ptr;
90 ret = stream_enqueue(stream, buf, len);
93 wake_up_interruptible(&(stream->intr_queue));
100 static void palacios_stream_close(void * stream_ptr) {
101 struct stream_buffer * stream = (struct stream_buffer *)stream_ptr;
103 free_ringbuf(stream->buf);
104 list_del(&(stream->stream_node));
109 struct v3_stream_hooks palacios_stream_hooks = {
110 .open = palacios_stream_open,
111 .write = palacios_stream_write,
112 .close = palacios_stream_close,
116 void palacios_init_stream() {
117 INIT_LIST_HEAD(&(global_streams));
118 V3_Init_Stream(&palacios_stream_hooks);
122 void palacios_deinit_stream() {
123 if (!list_empty(&(global_streams))) {
124 printk("Error removing module with open streams\n");