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.


virtual console works with stream-serial implementation
Lei Xia [Mon, 8 Nov 2010 19:41:51 +0000 (13:41 -0600)]
add reparent_threadd os hooks, In Linux host, every kernel thread created in Palacios
has to call reparent_threadd to detach itself from the user process.

palacios/include/devices/serial.h
palacios/include/palacios/vmm.h
palacios/include/palacios/vmm_stream.h
palacios/src/devices/serial.c
palacios/src/devices/stream.c
palacios/src/palacios/vmm_io.c

index f71159c..78ff076 100644 (file)
    to different kinds of frontend devices that can act as a stream */
 
 struct v3_stream_ops  {
+    /* called by serial device to the backend stream device */
     int (*read)(char *buf, uint_t len, void *private_data);
     int (*write)(char *buf, uint_t len, void *private_data);
+
+    /* called by backend device to frontend serial device */
+    int (*input)(char *buf, uint_t len, void *front_data);
+    void *front_data;
 };
 
 
index a5b47dc..dad24f6 100644 (file)
@@ -211,18 +211,27 @@ struct guest_info;
     } while (0)
 
 
-
-
+#define V3_Reparent_Threadd()                                  \
+    do {                                                       \
+       if((os_hooks) && (os_hooks)->reparent_threaded) {       \
+           (os_hooks)->reparent_threaded();                    \
+       }                                                       \
+    } while(0)
 
 /* ** */
 
 #define V3_ASSERT(x)                                                   \
     do {                                                               \
+       extern struct v3_os_hooks * os_hooks;                           \
        if (!(x)) {                                                     \
            PrintDebug("Failed assertion in %s: %s at %s, line %d, RA=%lx\n", \
                       __func__, #x, __FILE__, __LINE__,                \
                       (ulong_t) __builtin_return_address(0));          \
-           while(1);                                                   \
+           while(1){                                                   \
+               if ((os_hooks) && (os_hooks)->yield_cpu) {              \
+                       (os_hooks)->yield_cpu();                        \
+               }                                                       \
+           }                                                           \
        }                                                               \
     } while(0)                                                         \
        
@@ -292,7 +301,7 @@ struct v3_os_hooks {
     void (*interrupt_cpu)(struct v3_vm_info * vm, int logical_cpu, int vector);
     void (*call_on_cpu)(int logical_cpu, void (*fn)(void * arg), void * arg);
     void * (*start_thread_on_cpu)(int cpu_id, int (*fn)(void * arg), void * arg, char * thread_name);
-
+    void (*reparent_threadd)(void);
 };
 
 
index 02b7aed..ce4cb8f 100644 (file)
 
 #ifdef __V3VEE__
 
-#define V3_StreamOpen(path, mode)                                              \
+#define V3_StreamOpen(path, notify_fn, private_data, mode)                                             \
     ({                                                                 \
        extern struct v3_stream_hooks *stream_hooks;                            \
        ((stream_hooks) && (stream_hooks)->stream_open) ?                               \
-           (stream_hooks)->stream_open((path), (mode)) : NULL;         \
+           (stream_hooks)->stream_open((path), (notify_fn), (private_data), (mode)) : NULL;            \
     })
 
 #define V3_StreamRead(stream, b, l)                                    \
 #define STREAM_OPEN_MODE_WRITE (1 << 1)
 
 struct v3_stream_hooks {
-    void *(*stream_open)(const char *path, int mode);
+    void *(*stream_open)(const char *path, void (*notify)(void *), void *private_data, int mode);
     int (*stream_read)(void *stream, char *buf, int len);
     int (*stream_write)(void *stream, char *buf, int len);
     int (*stream_close)(void *stream);
-
 };
 
 
index 7d0c10e..1cdcc80 100644 (file)
@@ -12,6 +12,7 @@
  * All rights reserved.
  *
  * Author: Rumou Duan <duanrumou@gmail.com>
+ *             Lei Xia <lxia@northwestern.edu>
  *
  * This is free software.  You are permitted to use,
  * redistribute, and modify it as specified in the file "V3VEE_LICENSE".
@@ -289,6 +290,7 @@ struct serial_port {
     struct v3_stream_ops *stream_ops;
     void                 *backend_data;
 
+    struct vm_device * vm_dev;
 };
 
 
@@ -297,8 +299,6 @@ struct serial_state {
     struct serial_port com2;
     struct serial_port com3;
     struct serial_port com4;
-
-    
 };
 
 
@@ -455,19 +455,6 @@ static int dequeue_data(struct serial_buffer * buf, uint8_t * data,
     return 0;
 }
 
-/*
-static void printBuffer(struct serial_buffer * buf) {
-    int i = 0;
-
-    for (i = 0; i < SERIAL_BUF_LEN; i++) {
-       PrintDebug(" %d ", buf->buffer[i]);
-    }
-
-    PrintDebug("\n the number of elements is %d \n", getNumber(buf));
-}
-*/
-
-//note: write to data port is NOT implemented and corresponding codes are commented out
 static int write_data_port(struct guest_info * core, uint16_t port, 
                           void * src, uint_t length, struct vm_device * dev) {
     struct serial_state * state = (struct serial_state *)dev->private_data;
@@ -543,8 +530,8 @@ static int read_data_port(struct guest_info * core, uint16_t port,
        *val = com_port->dll.data;
     } else {
        dequeue_data(&(com_port->rx_buffer), val, com_port, dev);
-    }
-    
+    }    
+       
     return length;
 }
 
@@ -931,11 +918,21 @@ static int init_serial_port(struct serial_port * com) {
     return 0;
 }
 
+static int serial_input(char *buf, uint_t len, void *front_data){
+    struct serial_port *com_port = (struct serial_port *)front_data;
+    int i;
+
+    for(i=0; i<len; i++){
+       queue_data(&(com_port->rx_buffer), buf[i], com_port, com_port->vm_dev);
+    }
+
+    return len;
+}
+
 static int serial_init(struct v3_vm_info * vm, v3_cfg_tree_t * cfg) {
     struct serial_state * state = (struct serial_state *)V3_Malloc(sizeof(struct serial_state));
     char * dev_id = v3_cfg_val(cfg, "ID");
 
-    PrintDebug("UART: init_device\n");
     init_serial_port(&(state->com1));
     init_serial_port(&(state->com2));
     init_serial_port(&(state->com3));
@@ -946,14 +943,19 @@ static int serial_init(struct v3_vm_info * vm, v3_cfg_tree_t * cfg) {
     state->com3.irq_number = COM3_IRQ;
     state->com4.irq_number = COM4_IRQ;
 
-
     struct vm_device * dev = v3_allocate_device(dev_id, &dev_ops, state);
-
     if (v3_attach_device(vm, dev) == -1) {
        PrintError("Could not attach device %s\n", dev_id);
        return -1;
     }
 
+    state->com1.vm_dev = dev;
+    state->com2.vm_dev = dev;
+    state->com3.vm_dev = dev;
+    state->com4.vm_dev = dev;  
+
+    PrintDebug("Serial device attached\n");
+
     v3_dev_hook_io(dev, COM1_DATA_PORT, &read_data_port, &write_data_port);
     v3_dev_hook_io(dev, COM1_IRQ_ENABLE_PORT, &read_ctrl_port, &write_ctrl_port);
     v3_dev_hook_io(dev, COM1_FIFO_CTRL_PORT, &read_ctrl_port, &write_ctrl_port);
@@ -990,6 +992,8 @@ static int serial_init(struct v3_vm_info * vm, v3_cfg_tree_t * cfg) {
     v3_dev_hook_io(dev, COM4_MODEM_STATUS_PORT, &read_status_port, &write_status_port);
     v3_dev_hook_io(dev, COM4_SCRATCH_PORT, &read_ctrl_port, &write_ctrl_port);
 
+    PrintDebug("Serial ports hooked\n");
+
     return 0;
 }
 
@@ -1001,6 +1005,9 @@ int v3_stream_register_serial(struct vm_device * serial_dev, struct v3_stream_op
     state->com1.backend_data = private_data;
     /* bind to other ports here */
 
+    ops->input = serial_input;
+    ops->front_data = &(state->com1);
+
     return 0;
 }
 
index 0c6aed2..1b0d5c7 100644 (file)
 #include <devices/serial.h>
 
 struct stream_state {
-    void *stream;
+    void *stream_in;
+    void *stream_out;
     struct vm_device *frontend_dev;
+    struct v3_stream_ops stream_ops;
 };
 
-
 static int stream_read(char *buf, uint_t length, void *private_data) 
 {
     struct vm_device *dev = (struct vm_device *) private_data;
     struct stream_state *state = (struct stream_state *) dev->private_data;
     
-    return V3_StreamRead(state->stream,buf,length);
+    return V3_StreamRead(state->stream_out,buf,length);
 }
 
 static int stream_write(char *buf, uint_t length, void *private_data) 
@@ -45,15 +46,18 @@ static int stream_write(char *buf, uint_t length, void *private_data)
     struct vm_device *dev = (struct vm_device *) private_data;
     struct stream_state *state = (struct stream_state *) dev->private_data;
     
-    return V3_StreamWrite(state->stream,buf,length);
+    return V3_StreamWrite(state->stream_out,buf,length);
 }
 
 
-
-static struct v3_stream_ops stream_ops = {
-    .write = stream_write,
-    .read = stream_read,
-};
+static void notify(void * data){
+    struct stream_state *state = (struct stream_state *)data;
+    char temp[1024];
+    int len;   
+       
+    len = V3_StreamRead(state->stream_in, temp, 1024); 
+    state->stream_ops.input(temp, len, state->stream_ops.front_data);
+}
 
 static struct v3_device_ops dev_ops = {
     .free = NULL,
@@ -68,42 +72,43 @@ static int stream_init(struct v3_vm_info * vm, v3_cfg_tree_t * cfg)
     const char * frontend_tag = v3_cfg_val(frontend_cfg, "tag");
     struct vm_device * frontend = v3_find_dev(vm, frontend_tag);
     char * dev_id = v3_cfg_val(cfg, "ID");
-    char * path = v3_cfg_val(cfg, "localname");
+    char * stream_in = v3_cfg_val(cfg, "stream_in");
+    char * stream_out = v3_cfg_val(cfg, "stream_out");
     struct stream_state *state;
 
-    /* read configuration */
+
     V3_ASSERT(frontend_cfg);
     V3_ASSERT(frontend_tag);
     V3_ASSERT(frontend);
+    V3_ASSERT(stream_in);
+    V3_ASSERT(stream_out);
 
-    
-    /* allocate state */
     state = (struct stream_state *)V3_Malloc(sizeof(struct stream_state));
     V3_ASSERT(state);
     state->frontend_dev = frontend;
-    V3_ASSERT(path);
-       
-    /* The system is responsible for interpreting the localname of the stream */
-    state->stream = V3_StreamOpen(path, STREAM_OPEN_MODE_READ | STREAM_OPEN_MODE_WRITE);
-    if (!state->stream) {
-       PrintError("Could not open localname %s\n", path);
+
+    state->stream_out = V3_StreamOpen(stream_out, NULL, NULL, STREAM_OPEN_MODE_READ | STREAM_OPEN_MODE_WRITE);
+    state->stream_in = V3_StreamOpen(stream_in, notify, state, STREAM_OPEN_MODE_READ | STREAM_OPEN_MODE_WRITE);
+    if (!state->stream_out || !state->stream_in) {
+       PrintError("Could not open stream %s %s\n", stream_in, stream_out);
        V3_Free(state);
        return -1;
     }
-
-    /* allocate device */
+       
     struct vm_device *dev = v3_allocate_device(dev_id, &dev_ops, state);
     V3_ASSERT(dev);
 
-    /* attach device to virtual machine */
     if (v3_attach_device(vm, dev) == -1) {
        PrintError("Could not attach device %s\n", dev_id);
        V3_Free(state);
        return -1;
     }
 
-    v3_stream_register_serial(frontend, &stream_ops, dev);
-       
+    state->stream_ops.read = stream_read;
+    state->stream_ops.write = stream_write;
+
+    v3_stream_register_serial(frontend, &(state->stream_ops), dev);
+
     return 0;
 }
 
index d094d79..5f762e4 100644 (file)
@@ -124,7 +124,6 @@ int v3_hook_io_port(struct v3_vm_info * vm, uint16_t port,
     io_hook->write = write;
   }
 
-
   io_hook->priv_data = priv_data;
 
   if (insert_io_hook(vm, io_hook)) {