6 #include <linux/errno.h>
7 #include <linux/percpu.h>
8 #include <linux/sched.h>
10 #include <interfaces/vmm_stream.h>
11 #include "palacios-stream.h"
13 static struct list_head global_streams;
15 static 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 int open_stream(const char * name) {
43 struct stream_buffer * find_stream_by_name(struct v3_guest * guest, const char * name) {
44 struct stream_buffer * stream = NULL;
45 struct list_head * stream_list = NULL;
48 stream_list = &global_streams;
50 stream_list = &(guest->streams);
53 list_for_each_entry(stream, stream_list, stream_node) {
54 if (strncmp(stream->name, name, STREAM_NAME_LEN) == 0) {
63 static void * palacios_stream_open(const char * name, void * private_data) {
64 struct v3_guest * guest = (struct v3_guest *)private_data;
65 struct stream_buffer * stream = NULL;
67 if (find_stream_by_name(guest, name) != NULL) {
68 printk("Stream already exists\n");
72 stream = kmalloc(sizeof(struct stream_buffer), GFP_KERNEL);
74 stream->buf = create_ringbuf(STREAM_BUF_SIZE);
75 stream->guest = guest;
77 strncpy(stream->name, name, STREAM_NAME_LEN - 1);
79 init_waitqueue_head(&(stream->intr_queue));
80 spin_lock_init(&(stream->lock));
83 list_add(&(stream->stream_node), &(global_streams));
85 list_add(&(stream->stream_node), &(guest->streams));
92 static int palacios_stream_write(void * stream_ptr, char * buf, int len) {
93 struct stream_buffer * stream = (struct stream_buffer *)stream_ptr;
96 ret = stream_enqueue(stream, buf, len);
99 wake_up_interruptible(&(stream->intr_queue));
106 static void palacios_stream_close(void * stream_ptr) {
107 struct stream_buffer * stream = (struct stream_buffer *)stream_ptr;
109 free_ringbuf(stream->buf);
110 list_del(&(stream->stream_node));
115 struct v3_stream_hooks palacios_stream_hooks = {
116 .open = palacios_stream_open,
117 .write = palacios_stream_write,
118 .close = palacios_stream_close,
122 void palacios_init_stream() {
123 INIT_LIST_HEAD(&(global_streams));
124 V3_Init_Stream(&palacios_stream_hooks);
128 void palacios_deinit_stream() {
129 if (!list_empty(&(global_streams))) {
130 printk("Error removing module with open streams\n");