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"
12 #include "palacios-ringbuf.h"
14 static struct list_head global_streams;
16 int stream_enqueue(struct stream_buffer * stream, char * buf, int len) {
19 bytes = ringbuf_write(stream->buf, buf, len);
25 int stream_dequeue(struct stream_buffer * stream, char * buf, int len) {
28 bytes = ringbuf_read(stream->buf, buf, len);
33 int stream_datalen(struct stream_buffer * stream){
34 return ringbuf_data_len(stream->buf);
38 struct stream_buffer * find_stream_by_name(struct v3_guest * guest, const char * name) {
39 struct stream_buffer * stream = NULL;
40 struct list_head * stream_list = NULL;
43 stream_list = &global_streams;
45 stream_list = &(guest->streams);
48 list_for_each_entry(stream, stream_list, stream_node) {
49 if (strncmp(stream->name, name, STREAM_NAME_LEN) == 0) {
58 static void * palacios_stream_open(const char * name, void * private_data) {
59 struct v3_guest * guest = (struct v3_guest *)private_data;
60 struct stream_buffer * stream = NULL;
62 if (find_stream_by_name(guest, name) != NULL) {
63 printk("Stream already exists\n");
67 stream = kmalloc(sizeof(struct stream_buffer), GFP_KERNEL);
69 stream->buf = create_ringbuf(STREAM_BUF_SIZE);
70 stream->guest = guest;
72 strncpy(stream->name, name, STREAM_NAME_LEN - 1);
74 init_waitqueue_head(&(stream->intr_queue));
75 spin_lock_init(&(stream->lock));
78 list_add(&(stream->stream_node), &(global_streams));
80 list_add(&(stream->stream_node), &(guest->streams));
87 static int palacios_stream_write(void * stream_ptr, char * buf, int len) {
88 struct stream_buffer * stream = (struct stream_buffer *)stream_ptr;
91 ret = stream_enqueue(stream, buf, len);
94 wake_up_interruptible(&(stream->intr_queue));
101 static void palacios_stream_close(void * stream_ptr) {
102 struct stream_buffer * stream = (struct stream_buffer *)stream_ptr;
104 free_ringbuf(stream->buf);
105 list_del(&(stream->stream_node));
110 struct v3_stream_hooks palacios_stream_hooks = {
111 .open = palacios_stream_open,
112 .write = palacios_stream_write,
113 .close = palacios_stream_close,
117 void palacios_init_stream() {
118 INIT_LIST_HEAD(&(global_streams));
119 V3_Init_Stream(&palacios_stream_hooks);
123 void palacios_deinit_stream() {
124 if (!list_empty(&(global_streams))) {
125 printk("Error removing module with open streams\n");