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.


Merge branch 'devel' of palacios@newskysaw.cs.northwestern.edu:/home/palacios/palacio...
Lei Xia [Thu, 1 Sep 2011 15:30:07 +0000 (10:30 -0500)]
linux_module/mm.c
linux_module/palacios-stubs.c
linux_module/vm.c
linux_usr/v3_cons_sc.c [new file with mode: 0644]
linux_usr/v3_mem.c
palacios/src/palacios/vmm.c
palacios/src/palacios/vmm_string.c
palacios/src/palacios/vmm_xml.c
palacios/src/palacios/vmx.c

index a62b55a..04dcab3 100644 (file)
@@ -65,7 +65,7 @@ static uintptr_t alloc_contig_pgs(u64 num_pages, u32 alignment) {
        start = ((alignment - (pool.base_addr % alignment)) >> 12);
     }
 
-    printk("\t Start idx %d (base_addr=%llu)\n", start, (u64)pool.base_addr);
+    printk("\t Start idx %d (base_addr=%p)\n", start, (void *)(u64)pool.base_addr);
 
     for (i = start; i < (pool.num_pages - num_pages); i += step) {
        if (get_page_bit(i) == 0) {
index 31fcdbf..36f7625 100644 (file)
@@ -91,6 +91,7 @@ palacios_alloc(unsigned int size) {
        addr = kmalloc(size, GFP_KERNEL);
     }
     mallocs++;
+
  
     return addr;
 }
@@ -496,7 +497,7 @@ int palacios_vmm_init( void )
     
     printk("palacios_init starting - calling init_v3\n");
     
-    Init_V3(&palacios_os_hooks, nr_cpu_ids);
+    Init_V3(&palacios_os_hooks, num_online_cpus());
 
     return 0;
 
index 1702ffa..f53a598 100644 (file)
@@ -12,7 +12,7 @@
 #include <linux/poll.h>
 #include <linux/anon_inodes.h>
 #include <linux/sched.h>
-
+#include <linux/vmalloc.h>
 #include <linux/file.h>
 #include <linux/spinlock.h>
 #include <linux/rbtree.h>
@@ -290,7 +290,7 @@ int stop_palacios_vm(struct v3_guest * guest) {
 
     cdev_del(&(guest->cdev));
 
-    kfree(guest->img);
+    vfree(guest->img);
     kfree(guest);
 
     return 0;
diff --git a/linux_usr/v3_cons_sc.c b/linux_usr/v3_cons_sc.c
new file mode 100644 (file)
index 0000000..3b9e192
--- /dev/null
@@ -0,0 +1,618 @@
+/* 
+ * V3 Console utility
+ * Taken from Palacios console display in MINIX ( by Erik Van der Kouwe )
+ * (c) Jack lange, 2010
+ */
+
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <sys/ioctl.h> 
+#include <errno.h>
+#include <assert.h>
+#include <string.h>
+#include <fcntl.h>
+#include <unistd.h>
+#include <curses.h>
+#include <termios.h>
+#include <linux/kd.h>
+#include <linux/keyboard.h>
+
+#include "v3_ctrl.h"
+
+static int use_curses = 0;
+static int debug_enable = 1;
+
+
+typedef enum { CONSOLE_CURS_SET = 1,
+              CONSOLE_CHAR_SET = 2,
+              CONSOLE_SCROLL = 3,
+              CONSOLE_UPDATE = 4,
+               CONSOLE_RESOLUTION = 5 } console_op_t;
+
+
+
+static struct {
+    WINDOW * win;
+    int x;
+    int y;
+    int rows;
+    int cols;
+    struct termios termios_old;
+    unsigned char old_kbd_mode;
+} console;
+
+
+struct cursor_msg {
+    int x;
+    int y;
+} __attribute__((packed));
+
+struct character_msg {
+    int x;
+    int y;
+    char c;
+    unsigned char style;
+} __attribute__((packed));
+
+struct scroll_msg {
+    int lines;
+} __attribute__((packed));
+
+struct resolution_msg {
+    int cols;
+    int rows;
+} __attribute__((packed));
+
+
+struct cons_msg {
+    unsigned char op;
+    union {
+       struct cursor_msg cursor;
+       struct character_msg  character;
+       struct scroll_msg scroll;
+       struct resolution_msg resolution;
+    };
+} __attribute__((packed)); 
+
+
+
+
+static int handle_char_set(struct character_msg * msg) {
+    char c = msg->c;
+
+    if (debug_enable) {
+       fprintf(stderr, "setting char (%c), at (x=%d, y=%d)\n", c, msg->x, msg->y);
+    }
+
+    if (c == 0) {
+       c = ' ';
+    }
+
+
+    if ((c < ' ') || (c >= 127)) {
+       fprintf(stderr, "unexpected control character %d\n", c);
+       c = '?';
+    }
+
+    if (use_curses) {
+       /* clip whatever falls outside the visible area to avoid errors */
+       if ((msg->x < 0) || (msg->y < 0) ||
+           (msg->x > console.win->_maxx) || 
+           (msg->y > console.win->_maxy)) {
+
+           fprintf(stderr, "Char out of range (x=%d,y=%d) MAX:(x=%d,y=%d)\n",
+                   msg->x, msg->y, console.win->_maxx, console.win->_maxy);
+           return -1;
+       }
+
+       if ((msg->x == console.win->_maxx) &&
+           (msg->y == console.win->_maxy)) {
+           return -1;
+       }
+
+       mvwaddch(console.win, msg->y, msg->x, c);
+
+    } else {
+       //stdout text display
+       while (console.y < msg->y) {
+           printf("\n");
+           console.x = 0;
+           console.y++;
+       }
+
+       while (console.x < msg->x) {
+           printf(" ");
+           console.x++;
+       }
+
+       printf("%c", c);
+       console.x++;
+
+       assert(console.x <= console.cols); 
+
+       if (console.x == console.cols) {
+           printf("\n");
+           console.x = 0;
+           console.y++;
+       }
+    }
+
+    return 0;
+}
+
+int handle_curs_set(struct cursor_msg * msg) {
+    if (debug_enable) {
+       fprintf(stderr, "cursor set: (x=%d, y=%d)\n", msg->x, msg->y);
+    }
+
+    if (use_curses) {
+       /* nothing to do now, cursor is set before update to make sure it isn't 
+        * affected by character_set
+        */
+
+       console.x = msg->x;
+       console.y = msg->y;
+    }
+    
+    return 0;
+}
+
+
+int handle_scroll(struct scroll_msg * msg) {
+    int lines = msg->lines;
+
+    if (debug_enable) {
+       fprintf(stderr, "scroll: %d lines\n", lines);
+    }
+
+
+    assert(lines >= 0);
+
+    if (use_curses) {
+       while (lines > 0) {
+           scroll(console.win);
+           lines--;
+       }
+    } else {
+       console.y -= lines;     
+    }
+}
+
+int handle_text_resolution(struct resolution_msg * msg) {
+    if (debug_enable) {
+       fprintf(stderr, "text resolution: rows=%d, cols=%d\n", msg->rows, msg->cols);
+    }
+
+
+    console.rows = msg->rows;
+    console.cols = msg->cols;
+
+    return 0;
+}
+
+int handle_update( void ) {
+    if (debug_enable) {
+       fprintf(stderr, "update\n");
+    }    
+
+    if (use_curses) {
+
+       if ( (console.x >= 0) && (console.y >= 0) &&
+            (console.x <= console.win->_maxx) &&
+            (console.y <= console.win->_maxy) ) {
+
+           wmove(console.win, console.y, console.x);
+
+       }
+
+       wrefresh(console.win);
+    } else {
+       fflush(stdout);
+    }
+}
+
+
+int handle_console_msg(int cons_fd) {
+    int ret = 0;
+    struct cons_msg msg;
+
+    ret = read(cons_fd, &msg, sizeof(struct cons_msg));
+
+    switch (msg.op) {
+       case CONSOLE_CURS_SET:
+           //      printf("Console cursor set (x=%d, y=%d)\n", msg.cursor.x, msg.cursor.y);
+           handle_curs_set(&(msg.cursor));
+           break;
+       case CONSOLE_CHAR_SET:
+           handle_char_set(&(msg.character));
+           /*      printf("Console character set (x=%d, y=%d, c=%c, style=%c)\n", 
+             msg.character.x, msg.character.y, msg.character.c, msg.character.style);*/
+           break;
+       case CONSOLE_SCROLL:
+           //  printf("Console scroll (lines=%d)\n", msg.scroll.lines);
+           handle_scroll(&(msg.scroll));
+           break;
+       case CONSOLE_UPDATE:
+           // printf("Console update\n");
+           handle_update();
+           break;
+       case CONSOLE_RESOLUTION:
+           handle_text_resolution(&(msg.resolution));
+           break;
+       default:
+           printf("Invalid console message operation (%d)\n", msg.op);
+           break;
+    }
+
+    return 0;
+}
+
+
+int send_key(int cons_fd, char scan_code) {
+
+    return 0;
+}
+
+
+
+void handle_exit(void) {
+    fprintf(stderr, "Exiting from console terminal\n");
+
+    if (use_curses) {
+       endwin();
+    }
+
+    //    tcsetattr(STDIN_FILENO, TCSANOW, &console.termios_old);
+
+    // ioctl(STDIN_FILENO, KDSKBMODE, K_XLATE);
+}
+
+
+#define NO_KEY { 0, 0 }
+
+struct key_code {
+    unsigned char scan_code;
+    unsigned char capital;
+};
+
+static const struct key_code ascii_to_key_code[] = {             // ASCII Value Serves as Index
+    NO_KEY,         NO_KEY,         NO_KEY,         NO_KEY,      // 0x00 - 0x03
+    NO_KEY,         NO_KEY,         NO_KEY,         NO_KEY,      // 0x04 - 0x07
+    { 0x0E, 0 },    { 0x0F, 0 },    { 0x1C, 0 },    NO_KEY,      // 0x08 - 0x0B
+    NO_KEY,         { 0x1C, 0 },    NO_KEY,         NO_KEY,      // 0x0C - 0x0F
+    NO_KEY,         NO_KEY,         NO_KEY,         NO_KEY,      // 0x10 - 0x13
+    NO_KEY,         NO_KEY,         NO_KEY,         NO_KEY,      // 0x14 - 0x17
+    NO_KEY,         NO_KEY,         NO_KEY,         { 0x01, 0 }, // 0x18 - 0x1B
+    NO_KEY,         NO_KEY,         NO_KEY,         NO_KEY,      // 0x1C - 0x1F
+    { 0x39, 0 },    { 0x02, 1 },    { 0x28, 1 },    { 0x04, 1 }, // 0x20 - 0x23
+    { 0x05, 1 },    { 0x06, 1 },    { 0x08, 1 },    { 0x28, 0 }, // 0x24 - 0x27
+    { 0x0A, 1 },    { 0x0B, 1 },    { 0x09, 1 },    { 0x0D, 1 }, // 0x28 - 0x2B
+    { 0x33, 0 },    { 0x0C, 0 },    { 0x34, 0 },    { 0x35, 0 }, // 0x2C - 0x2F
+    { 0x0B, 0 },    { 0x02, 0 },    { 0x03, 0 },    { 0x04, 0 }, // 0x30 - 0x33
+    { 0x05, 0 },    { 0x06, 0 },    { 0x07, 0 },    { 0x08, 0 }, // 0x34 - 0x37
+    { 0x09, 0 },    { 0x0A, 0 },    { 0x27, 1 },    { 0x27, 0 }, // 0x38 - 0x3B
+    { 0x33, 1 },    { 0x0D, 0 },    { 0x34, 1 },    { 0x35, 1 }, // 0x3C - 0x3F
+    { 0x03, 1 },    { 0x1E, 1 },    { 0x30, 1 },    { 0x2E, 1 }, // 0x40 - 0x43
+    { 0x20, 1 },    { 0x12, 1 },    { 0x21, 1 },    { 0x22, 1 }, // 0x44 - 0x47
+    { 0x23, 1 },    { 0x17, 1 },    { 0x24, 1 },    { 0x25, 1 }, // 0x48 - 0x4B
+    { 0x26, 1 },    { 0x32, 1 },    { 0x31, 1 },    { 0x18, 1 }, // 0x4C - 0x4F
+    { 0x19, 1 },    { 0x10, 1 },    { 0x13, 1 },    { 0x1F, 1 }, // 0x50 - 0x53
+    { 0x14, 1 },    { 0x16, 1 },    { 0x2F, 1 },    { 0x11, 1 }, // 0x54 - 0x57
+    { 0x2D, 1 },    { 0x15, 1 },    { 0x2C, 1 },    { 0x1A, 0 }, // 0x58 - 0x5B
+    { 0x2B, 0 },    { 0x1B, 0 },    { 0x07, 1 },    { 0x0C, 1 }, // 0x5C - 0x5F
+    { 0x29, 0 },    { 0x1E, 0 },    { 0x30, 0 },    { 0x2E, 0 }, // 0x60 - 0x63
+    { 0x20, 0 },    { 0x12, 0 },    { 0x21, 0 },    { 0x22, 0 }, // 0x64 - 0x67
+    { 0x23, 0 },    { 0x17, 0 },    { 0x24, 0 },    { 0x25, 0 }, // 0x68 - 0x6B
+    { 0x26, 0 },    { 0x32, 0 },    { 0x31, 0 },    { 0x18, 0 }, // 0x6C - 0x6F
+    { 0x19, 0 },    { 0x10, 0 },    { 0x13, 0 },    { 0x1F, 0 }, // 0x70 - 0x73
+    { 0x14, 0 },    { 0x16, 0 },    { 0x2F, 0 },    { 0x11, 0 }, // 0x74 - 0x77
+    { 0x2D, 0 },    { 0x15, 0 },    { 0x2C, 0 },    { 0x1A, 1 }, // 0x78 - 0x7B
+    { 0x2B, 1 },    { 0x1B, 1 },    { 0x29, 1 },    { 0x0E, 0 }  // 0x7C - 0x7F
+};
+
+
+
+#define writeit(fd,c)  do { fprintf(stderr,"scancode 0x%x\n",(c)); if (write((fd),&(c),1)!=1) { return -1; } } while (0)
+
+int send_char_to_palacios_as_scancodes(int fd, unsigned char c)
+{
+    unsigned char sc;
+
+    fprintf(stderr,"key '%c'\n",c);
+
+    if (c<0x80) { 
+       struct key_code k = ascii_to_key_code[c];
+       
+       if (k.scan_code==0 && k.capital==0) { 
+           fprintf(stderr,"Cannot send key '%c' to palacios as it maps to no scancode\n",c);
+       } else {
+           if (k.capital) { 
+               //shift down
+               sc = 0x2a ; // left shift down
+               writeit(fd,sc);
+           }
+           
+           
+           sc = k.scan_code;
+           
+           writeit(fd,sc);  // key down
+           
+           sc |= 0x80;      // key up
+           
+           writeit(fd,sc);
+           
+           if (k.capital) { 
+               sc = 0x2a | 0x80;
+               writeit(fd,sc);
+           }
+       }
+           
+    } else {
+
+
+       fprintf(stderr,"Cannot send key '%c' to palacios because it is >=0x80\n",c);
+
+/*     switch (key) {  */
+/*         case 0xffe1:  //left shift */
+/*             scancode = 0x2a; */
+/*             break; */
+
+/*         case 0xffe2:  //right shift */
+/*             scancode = 0x36; */
+/*             break; */
+
+/*         case 0xffe3:  //left ctrl */
+/*         case 0xffe4:  //right ctrl */
+/*             scancode = 0x1d;   // translated as left ctrl */
+/*             break; */
+
+/*         case 0xffe7:  //left meta */
+/*         case 0xffe8:  //right meta */
+/*         case 0xffe9:  //left alt */
+/*         case 0xffea:  //right alt */
+/*             scancode = 0x38;  // translated as a left alt */
+/*             break;  */
+
+/*         case 0xff08: // backspace */
+/*             scancode = 0x0e; */
+/*             break;  */
+
+/*         case 0xff09: // tab */
+/*             scancode = 0x0f;   */
+/*             break;  */
+
+/*         case 0xff0d: // return */
+/*             scancode = 0x1c; */
+/*             break;  */
+
+/*         case 0xff1b: // escape */
+/*             scancode = 0x01; */
+/*             break;  */
+
+/*         case 0xff63: // insert */
+/*             scancode = 0x52; */
+/*             break;  */
+
+/*         case 0xffff: // delete */
+/*             scancode = 0x53; */
+/*             break;  */
+
+/*         case 0xff50: // home */
+/*             scancode = 0x47; */
+/*             break;  */
+
+/*         case 0xff57: // end */
+/*             scancode = 0x4f; */
+/*             break;  */
+               
+/*         case 0xff55: // pageup */
+/*             scancode = 0x49; */
+/*             break;  */
+
+/*         case 0xff56: // pagedown */
+/*             scancode = 0x51; */
+/*             break;  */
+
+/*         case 0xff51: // left */
+/*             scancode = 0x4b; */
+/*             break;  */
+
+/*         case 0xff52: // up */
+/*             scancode = 0x48; */
+/*             break;  */
+
+/*         case 0xff53: // right */
+/*             scancode = 0x4d; */
+/*             break;  */
+
+/*         case 0xff54: // down */
+/*             scancode = 0x50; */
+/*             break;  */
+
+/*         case 0xffbe: // f1 */
+/*             scancode = 0x3b; */
+/*             break;  */
+/*         case 0xffbf: // f2 */
+/*             scancode = 0x3c; */
+/*             break;  */
+/*         case 0xffc0: // f3 */
+/*             scancode = 0x3d; */
+/*             break;  */
+/*         case 0xffc1: // f4 */
+/*             scancode = 0x3e; */
+/*             break;  */
+/*         case 0xffc2: // f5 */
+/*             scancode = 0x3f; */
+/*             break;  */
+/*         case 0xffc3: // f6 */
+/*             scancode = 0x40; */
+/*             break;  */
+/*         case 0xffc4: // f7 */
+/*             scancode = 0x41; */
+/*             break;  */
+/*         case 0xffc5: // f8 */
+/*             scancode = 0x42; */
+/*             break;  */
+/*         case 0xffc6: // f9 */
+/*             scancode = 0x43; */
+/*             break; */
+/*         case 0xffc7: // f10 */
+/*             scancode = 0x44; */
+/*             break;  */
+/*         case 0xffc8: // f11 */
+/*             scancode = 0x57; */
+/*             break;  */
+/*         case 0xffc9: // f12 */
+/*             scancode = 0x58; */
+/*             break;  */
+
+
+/*         default: */
+/*             scancode = 0; */
+/*             fprintf(stderr,"Ignoring key 0x%x (down=%d)\n", key, down); */
+/*     } */
+/*     } */
+    
+/*     if (scancode==0) {  */
+/*     return 0; */
+/*     } */
+       
+       
+/*     return scancode; */
+       
+    }
+    return 0;
+}
+    
+int main(int argc, char* argv[]) {
+    int vm_fd;
+    int cons_fd;
+    char * vm_dev = NULL;
+    struct termios termios;
+
+    use_curses = 1;
+
+    if (argc < 2) {
+       printf("Usage: ./v3_cons <vm_device>\n");
+       return -1;
+    }
+
+    vm_dev = argv[1];
+
+
+
+    vm_fd = open(vm_dev, O_RDONLY);
+
+    if (vm_fd == -1) {
+       printf("Error opening VM device: %s\n", vm_dev);
+       return -1;
+    }
+
+    cons_fd = ioctl(vm_fd, V3_VM_CONSOLE_CONNECT, NULL); 
+
+    /* Close the file descriptor.  */ 
+    close(vm_fd); 
+
+    if (cons_fd < 0) {
+       printf("Error opening stream Console\n");
+       return -1;
+    }
+
+    tcgetattr(STDIN_FILENO, &console.termios_old);
+    atexit(handle_exit);
+
+    console.x = 0;
+    console.y = 0;
+
+
+    if (use_curses) {
+       gettmode();
+       console.win = initscr();
+       
+       if (console.win == NULL) {
+           fprintf(stderr, "Error initialization curses screen\n");
+           exit(-1);
+       }
+
+       scrollok(console.win, 1);
+    }
+
+    /*
+    termios = console.termios_old;
+    termios.c_iflag &= ~(BRKINT | ICRNL | IGNBRK | IGNCR | IGNPAR);
+    termios.c_iflag &= ~(INLCR | INPCK | ISTRIP | IXOFF | IXON | PARMRK); 
+    //termios.c_iflag &= ~(ICRNL | INLCR );    
+
+    //  termios.c_iflag |= SCANCODES; 
+    //    termios.c_lflag &= ~(ECHO | ECHOE | ECHOK | ECHONL); 
+    //termios.c_lflag &= ~(ICANON | IEXTEN | ISIG | NOFLSH);
+    termios.c_lflag &= ~(ICANON | ECHO);
+
+    termios.c_cc[VMIN] = 1;
+    termios.c_cc[VTIME] = 0;
+
+    tcflush(STDIN_FILENO, TCIFLUSH);
+    tcsetattr(STDIN_FILENO, TCSANOW, &termios);
+    */    
+
+    raw();
+    cbreak();
+    noecho();
+    keypad(console.win, TRUE);
+
+    //ioctl(STDIN_FILENO, KDSKBMODE, K_RAW);
+
+    while (1) {
+       int ret; 
+       int bytes_read = 0;
+       fd_set rset;
+
+       FD_ZERO(&rset);
+       FD_SET(cons_fd, &rset);
+       FD_SET(STDIN_FILENO, &rset);
+
+       ret = select(cons_fd + 1, &rset, NULL, NULL, NULL);
+       
+       //      printf("Returned from select...\n");
+
+       if (ret == 0) {
+           continue;
+       } else if (ret == -1) {
+           perror("Select returned error...\n");
+           return -1;
+       }
+
+       if (FD_ISSET(cons_fd, &rset)) {
+           if (handle_console_msg(cons_fd) == -1) {
+               printf("Console Error\n");
+               return -1;
+           }
+       }
+
+       if (FD_ISSET(STDIN_FILENO, &rset)) {
+           unsigned char key = getch();
+
+           if (key == '\\') { // ESC
+               break;
+           } else if (key == '`') {
+               unsigned char sc = 0x44; // F10
+               writeit(cons_fd,sc);
+               sc |= 0x80;
+               writeit(cons_fd,sc);
+            }else {
+               if (send_char_to_palacios_as_scancodes(cons_fd,key)) {
+                   fprintf(stderr, "Error sendign key to console\n");
+                   return -1;
+               }
+           }
+           
+       }
+    } 
+
+    close(cons_fd);
+
+    return 0; 
+}
+
+
index e51ef18..b02cdeb 100644 (file)
@@ -48,7 +48,7 @@ int main(int argc, char * argv[]) {
     unsigned char * bitmap = NULL;
     int num_blocks = 0;    
     int reg_start = 0;
-
+    int mem_ready = 0;
 
     if (argc != 2) {
        printf("Usage: v3_mem <memory size (MB)>\n");
@@ -146,71 +146,155 @@ int main(int argc, char * argv[]) {
 
     }
     
+    while (!mem_ready) {
 
-    /* Scan bitmap for enough consecutive space */
-    {
-       // num_blocks: The number of blocks we need to find
-       // bitmap: bitmap of blocks (1 == allocatable)
-       // bitmap_entries: number of blocks in the system/number of bits in bitmap
-       // reg_start: The block index where our allocation will start
 
-       int i = 0;
-       int run_len = 0;
+       /* Scan bitmap for enough consecutive space */
+       {
+           // num_blocks: The number of blocks we need to find
+           // bitmap: bitmap of blocks (1 == allocatable)
+           // bitmap_entries: number of blocks in the system/number of bits in bitmap
+           // reg_start: The block index where our allocation will start
+           
+           int i = 0;
+           int run_len = 0;
+           
+           for (i = 0; i < bitmap_entries; i++) {
+               int i_major = i / 8;
+               int i_minor = i % 8;
+               
+               
+               if (!(bitmap[i_major] & (0x1 << i_minor))) {
+                   reg_start = i + 1; // skip the region start to next entry
+                   run_len = 0;
+                   continue;
+               }
+               
+               run_len++;
+
+               if (run_len >= num_blocks) {
+                   break;
+               }
+           }
 
-       for (i = 0; i < bitmap_entries; i++) {
-           int i_major = i / 8;
-           int i_minor = i % 8;
+       
+           if (run_len < num_blocks) {
+               fprintf(stderr, "Could not find enough consecutive memory blocks... (found %d)\n", run_len);
+               return -1;
+           }
+       }
+    
 
+       /* Offline memory blocks starting at reg_start */
+       {
+           int i = 0;
 
-           if (!(bitmap[i_major] & (0x1 << i_minor))) {
-               reg_start = i + 1; // skip the region start to next entry
-               run_len = 0;
-               continue;
-           }
+           for (i = 0; i < num_blocks; i++) {  
+               FILE * block_file = NULL;
+               char fname[256];
+
+               memset(fname, 0, 256);
+
+               snprintf(fname, 256, "%smemory%d/state", SYS_PATH, i + reg_start);
+           
+               block_file = fopen(fname, "r+");
+
+               if (block_file == NULL) {
+                   perror("Could not open block file");
+                   return -1;
+               }
 
-           run_len++;
 
-           if (run_len >= num_blocks) {
-               break;
+               printf("Offlining block %d (%s)\n", i + reg_start, fname);
+               fprintf(block_file, "offline\n");
+
+               fclose(block_file);
            }
        }
 
-       free(bitmap);
-       
-       if (run_len < num_blocks) {
-           fprintf(stderr, "Could not find enough consecutive memory blocks... (found %d)\n", run_len);
-           return -1;
-       }
-    }
-    
 
-    /* Offline memory blocks starting at reg_start */
-    {
-       int i = 0;
+       /*  We asked to offline set of blocks, but Linux could have lied. 
+        *  To be safe, check whether blocks were offlined and start again if not 
+        */
 
-       for (i = 0; i < num_blocks; i++) {      
-           FILE * block_file = NULL;
-           char fname[256];
+       {
+           int i = 0;
 
-           memset(fname, 0, 256);
+           mem_ready = 1; // Hopefully we are ok...
 
-           snprintf(fname, 256, "%smemory%d/state", SYS_PATH, i + reg_start);
-           
-           block_file = fopen(fname, "r+");
 
-           if (block_file == NULL) {
-               perror("Could not open block file");
-               return -1;
-           }
+           for (i = 0; i < num_blocks; i++) {
+               int block_fd = NULL;
+               char fname[BUF_SIZE];
+               char status_buf[BUF_SIZE];
+
 
+               memset(fname, 0, BUF_SIZE);
+               memset(status_buf, 0, BUF_SIZE);
 
-           printf("Offlining block %d (%s)\n", i + reg_start, fname);
-           fprintf(block_file, "offline\n");
+               snprintf(fname, BUF_SIZE, "%smemory%d/state", SYS_PATH, i + reg_start);
 
-           fclose(block_file);
+       
+               block_fd = open(fname, O_RDONLY);
+               
+               if (block_fd == -1) {
+                   perror("Could not open block file");
+                   return -1;
+               }
+                   
+               if (read(block_fd, status_buf, BUF_SIZE) <= 0) {
+                   perror("Could not read block status");
+                   return -1;
+               }
+
+               printf("Checking offlined block %d (%s)...", i + reg_start, fname);
+
+               int ret = strncmp(status_buf, "offline", strlen("offline"));
+
+               if (ret != 0) {
+                   int j = 0;
+                   int major = (i + reg_start) / 8;
+                   int minor = (i + reg_start) % 8;
+
+                   bitmap[major] &= ~(0x1 << minor); // mark the block as not removable in bitmap
+
+                   mem_ready = 0; // Keep searching
+
+                   printf("ERROR (%d)\n", ret);
+
+                   for (j = 0; j < i; j++) {
+                       FILE * block_file = NULL;
+                       char fname[256];
+                       
+                       memset(fname, 0, 256);
+                       
+                       snprintf(fname, 256, "%smemory%d/state", SYS_PATH, j + reg_start);
+                       
+                       block_file = fopen(fname, "r+");
+                       
+                       if (block_file == NULL) {
+                           perror("Could not open block file");
+                           return -1;
+                       }
+
+                       fprintf(block_file, "online\n");
+                       
+                       fclose(block_file);
+                   }
+                      
+
+                   break;
+               } 
+               
+               printf("OK\n");
+               
+           }
+           
+           
        }
     }
 
+    free(bitmap);
 
     /* Memory is offlined. Calculate size and phys start addr to send to Palacios */
 
index 317f219..34b6c2c 100644 (file)
@@ -154,7 +154,8 @@ void Shutdown_V3() {
     if ((os_hooks) && (os_hooks->call_on_cpu)) {
        for (i = 0; i < V3_CONFIG_MAX_CPUS; i++) {
            if (v3_cpu_types[i] != V3_INVALID_CPU) {
-               deinit_cpu((void *)(addr_t)i);
+               V3_Call_On_CPU(i, deinit_cpu, (void *)(addr_t)i);
+               //deinit_cpu((void *)(addr_t)i);
            }
        }
     }
index 725fa17..75a8975 100644 (file)
@@ -460,10 +460,14 @@ size_t strcspn(const char * s, const char * reject) {
        for (i = 0; i < reject_len; i++) {
            if (s[cnt] == reject[i]) {
                match = 1;
-               cnt++;
                break;
            }
        }
+
+       if (!match) {
+           cnt++;
+       }
+
     }
 
     return cnt;
index d6963c8..d09a176 100644 (file)
@@ -53,8 +53,6 @@ struct v3_xml_root {       // additional data for the root tag
     char *str_ptr;         // original xml string
     char *tmp_start;              // start of work area
     char *tmp_end;              // end of work area
-    char **ent;           // general entities (ampersand sequences)
-    char ***attr;         // default attributes
     short standalone;     // non-zero if <?xml standalone="yes"?>
     char err[V3_XML_ERRL]; // error string
 };
@@ -62,23 +60,24 @@ struct v3_xml_root {       // additional data for the root tag
 static char * empty_attrib_list[] = { NULL }; // empty, null terminated array of strings
 
 
+
 static void * tmp_realloc(void * old_ptr, size_t old_size, size_t new_size) {
-    void * new_buf = V3_Malloc(new_size);
+    void * new_buf = NULL; 
 
+    new_buf = V3_Malloc(new_size);
+    
     if (new_buf == NULL) {
         return NULL;
     }
 
+    memset(new_buf, 0, new_size);
+
     memcpy(new_buf, old_ptr, old_size);
     V3_Free(old_ptr);
 
     return new_buf;
 }
 
-
-
-
-
 // set an error string and return root
 static void v3_xml_err(struct v3_xml_root * root, char * xml_str, const char * err, ...) {
     va_list ap;
@@ -136,8 +135,6 @@ struct v3_xml * v3_xml_idx(struct v3_xml * xml, int idx) {
 // returns the value of the requested tag attribute or NULL if not found
 const char * v3_xml_attr(struct v3_xml * xml, const char * attr) {
     int i = 0;
-    int j = 1;
-    struct v3_xml_root * root = (struct v3_xml_root *)xml;
 
     if ((!xml) || (!xml->attr)) {
        return NULL;
@@ -151,24 +148,7 @@ const char * v3_xml_attr(struct v3_xml * xml, const char * attr) {
        return xml->attr[i + 1]; // found attribute
     }
 
-    while (root->xml.parent != NULL) {
-       root = (struct v3_xml_root *)root->xml.parent; // root tag
-    }
-
-    for (i = 0; 
-        ( (root->attr[i] != NULL) && 
-          (strcasecmp(xml->name, root->attr[i][0]) != 0) ); 
-        i++);
-
-    if (! root->attr[i]) {
-       return NULL; // no matching default attributes
-    }
-
-    while ((root->attr[i][j] != NULL) && (strcasecmp(attr, root->attr[i][j]) != 0)) {
-       j += 3;
-    }
-
-    return (root->attr[i][j] != NULL) ? root->attr[i][j + 1] : NULL; // found default
+    return NULL; // found default
 }
 
 // same as v3_xml_get but takes an already initialized va_list
@@ -219,11 +199,10 @@ static struct v3_xml * v3_xml_set_flag(struct v3_xml * xml, short flag)
 // for cdata sections, ' ' for attribute normalization, or '*' for non-cdata
 // attribute normalization. Returns s, or if the decoded string is longer than
 // s, returns a malloced string that must be freed.
-static char * v3_xml_decode(char * s, char ** ent, char t) {
+static char * v3_xml_decode(char * s, char t) {
     char * e;
     char * r = s;
-    char * m = s;
-    long b, c, d, l;
+    long c, l;
 
     // normalize line endings
     for (; *s; s++) { 
@@ -266,28 +245,6 @@ static char * v3_xml_decode(char * s, char ** ent, char t) {
            *(s++) = c; 
 
             memmove(s, strchr(s, ';') + 1, strlen(strchr(s, ';')));
-        } else if ( ( (*s == '&') && 
-                     ((t == '&') || (t == ' ') || (t == '*'))) ||
-                   ( (*s == '%') && (t == '%'))) { 
-           // entity reference`
-
-            for ( (b = 0); 
-                 (ent[b]) && (strncmp(s + 1, ent[b], strlen(ent[b])) != 0);
-                 (b += 2)); // find entity in entity list
-
-            if (ent[b++]) { // found a match
-                if (((c = strlen(ent[b])) - 1) > ((e = strchr(s, ';')) - s)) {
-                    l = (d = (s - r)) + c + strlen(e); // new length
-                    r = ((r == m) ? strcpy(V3_Malloc(l), r) : tmp_realloc(r, strlen(r), l));
-                    e = strchr((s = r + d), ';'); // fix up pointers
-                }
-
-                memmove(s + c, e + 1, strlen(e)); // shift rest of string
-                strncpy(s, ent[b], c); // copy in replacement text
-            } else {
-               // not a known entity
-               s++;
-           }
         } else if ( ( (t == ' ') || (t == '*')) && 
                    (isspace(*s))) {
            *(s++) = ' ';
@@ -331,16 +288,23 @@ static void v3_xml_char_content(struct v3_xml_root * root, char * s, size_t len,
     }
 
     s[len] = '\0'; // null terminate text (calling functions anticipate this)
-    len = strlen(s = v3_xml_decode(s, root->ent, t)) + 1;
+    len = strlen(s = v3_xml_decode(s, t)) + 1;
 
-    if (! *(xml->txt)) {
+    if (xml->txt[0] == '\0') { // empty string
        // initial character content
        xml->txt = s;
     } else { 
+
        // allocate our own memory and make a copy
-        xml->txt = (xml->flags & V3_XML_TXTM) ? 
-           (tmp_realloc(xml->txt, strlen(xml->txt), (l = strlen(xml->txt)) + len)) : 
-           (strcpy(V3_Malloc((l = strlen(xml->txt)) + len), xml->txt));
+       if (xml->flags & V3_XML_TXTM) {
+           xml->txt = (tmp_realloc(xml->txt, strlen(xml->txt), (l = strlen(xml->txt)) + len));
+       } else {
+           char * tmp = NULL;
+
+           tmp = V3_Malloc((l = strlen(xml->txt)) + len);
+           strcpy(tmp, xml->txt);
+           xml->txt = tmp;
+       }
 
         strcpy(xml->txt + l, s); // add new char content
        
@@ -367,37 +331,6 @@ static int v3_xml_close_tag(struct v3_xml_root * root, char * name, char * s) {
     return 0;
 }
 
-#if 0
-// checks for circular entity references, returns non-zero if no circular
-// references are found, zero otherwise
-static int v3_xml_ent_ok(char * name, char * s, char ** ent) {
-    int i;
-
-    for (; ; s++) {
-        while ((*s != '\0') && (*s != '&')) {
-           // find next entity reference
-           s++; 
-       }
-
-        if (*s == '\0') {
-           return 1;
-       }
-
-        if (strncmp(s + 1, name, strlen(name)) == 0) {
-           // circular ref.
-           return 0;
-       }
-
-        for (i = 0; (ent[i]) && (strncmp(ent[i], s + 1, strlen(ent[i]))); i += 2);
-
-        if ((ent[i] != NULL) && (v3_xml_ent_ok(name, ent[i + 1], ent) == 0)) {
-           return 0;
-       }
-    }
-}
-#endif
-
-
 
 // frees a tag attribute list
 static void v3_xml_free_attr(char **attr) {
@@ -416,16 +349,6 @@ static void v3_xml_free_attr(char **attr) {
 
     m = attr[i + 1]; // list of which names and values are malloced
 
-    for (i = 0; m[i]; i++) {
-        if (m[i] & V3_XML_NAMEM) {
-           V3_Free(attr[i * 2]);
-       }
-
-        if (m[i] & V3_XML_TXTM) {
-           V3_Free(attr[(i * 2) + 1]);
-       }
-    }
-
     V3_Free(m);
     V3_Free(attr);
 }
@@ -437,8 +360,6 @@ static void v3_xml_free_attr(char **attr) {
 
 // returns a new empty v3_xml structure with the given root tag name
 static struct v3_xml * v3_xml_new(const char * name) {
-    static char * ent[] = { "lt;", "&#60;", "gt;", "&#62;", "quot;", "&#34;",
-                           "apos;", "&#39;", "amp;", "&#38;", NULL };
 
     struct v3_xml_root * root = (struct v3_xml_root *)V3_Malloc(sizeof(struct v3_xml_root));
     memset(root, 0, sizeof(struct v3_xml_root));
@@ -448,11 +369,6 @@ static struct v3_xml * v3_xml_new(const char * name) {
     root->xml.txt = "";
     memset(root->err, 0, V3_XML_ERRL);
 
-    root->ent = V3_Malloc(sizeof(ent));
-    memcpy(root->ent, ent, sizeof(ent));
-
-    root->xml.attr = empty_attrib_list;
-    root->attr = (char ***)(empty_attrib_list);
 
     return &root->xml;
 }
@@ -579,9 +495,7 @@ static struct v3_xml * parse_str(char * buf, size_t len) {
     char last_char; 
     char * tag_ptr;
     char ** attr; 
-    char ** tmp_attr = NULL; // initialize a to avoid compile warning
     int attr_idx;
-    int i, j;
 
     root->str_ptr = buf;
 
@@ -626,17 +540,7 @@ static struct v3_xml * parse_str(char * buf, size_t len) {
                *(buf++) = '\0';
            }
 
-           // check if attribute follows tag
-            if ((*buf) && (*buf != '/') && (*buf != '>')) {
-               // there is an attribute
-               // find attributes for correct tag
-                for ((i = 0); 
-                    ((tmp_attr = root->attr[i]) && 
-                     (strcasecmp(tmp_attr[0], tag_ptr) != 0)); 
-                    (i++)) ;
-               
-               // 'tmp_attr' now points to the attribute list associated with 'tag_ptr'
-           }
+       
 
            // attributes are name value pairs, 
            //     2nd to last entry is null  (end of list)
@@ -660,7 +564,7 @@ static struct v3_xml * parse_str(char * buf, size_t len) {
                                        (2 * sizeof(char *))), 
                                       ((attr_cnt * (2 * sizeof(char *))) + 
                                        (2 * sizeof(char *))));
-               
+
                    attr[last_idx] = tmp_realloc(attr[last_idx - 2], 
                                                 attr_cnt,
                                                 (attr_cnt + 1)); 
@@ -668,7 +572,6 @@ static struct v3_xml * parse_str(char * buf, size_t len) {
                    attr = V3_Malloc(4 * sizeof(char *)); 
                    attr[last_idx] = V3_Malloc(2);
                }
-               
 
                 attr[attr_idx] = buf; // set attribute name
                 attr[val_idx] = ""; // temporary attribute value
@@ -678,9 +581,9 @@ static struct v3_xml * parse_str(char * buf, size_t len) {
                 buf += strcspn(buf, V3_XML_WS "=/>");
 
                 if ((*buf == '=') || isspace(*buf)) {
-                    
+
                    *(buf++) = '\0'; // null terminate tag attribute name
-                   
+
                    // eat whitespace (and more multiple '=' ?)
                    buf += strspn(buf, V3_XML_WS "=");
 
@@ -702,20 +605,7 @@ static struct v3_xml * parse_str(char * buf, size_t len) {
                            return NULL;
                         }
 
-                        for (j = 1; 
-                            ( (tmp_attr) && (tmp_attr[j]) && 
-                              (strcasecmp(tmp_attr[j], attr[attr_idx]) != 0)); 
-                            j += 3);
-
-                        attr[val_idx] = v3_xml_decode(attr[val_idx], root->ent, 
-                                                     ((tmp_attr && tmp_attr[j]) ? 
-                                                      *tmp_attr[j + 2] : 
-                                                      ' '));
-                       
-                        if ( (attr[val_idx] < tag_ptr) || 
-                            (attr[val_idx] > buf) ) {
-                            attr[last_idx][attr_cnt - 1] = V3_XML_TXTM; // value malloced
-                       }
+                        attr[val_idx] = v3_xml_decode(attr[val_idx], ' ');
                     }
                 }
 
@@ -801,6 +691,11 @@ static struct v3_xml * parse_str(char * buf, size_t len) {
         *buf = '\0';
         tag_ptr = ++buf;
 
+       /* Eat leading whitespace */
+       while (*buf && isspace(*buf)) {
+           buf++;
+       }
+
         if (*buf && (*buf != '<')) { 
            // tag character content
             while (*buf && (*buf != '<')) {
@@ -849,8 +744,6 @@ struct v3_xml * v3_xml_parse(char * buf) {
 // free the memory allocated for the v3_xml structure
 void v3_xml_free(struct v3_xml * xml) {
     struct v3_xml_root * root = (struct v3_xml_root *)xml;
-    int i, j;
-    char **a, *s;
 
     if (xml == NULL) {
         return;
@@ -861,36 +754,13 @@ void v3_xml_free(struct v3_xml * xml) {
 
     if (xml->parent == NULL) { 
        // free root tag allocations
-        
-       for (i = 10; root->ent[i]; i += 2) {
-           // 0 - 9 are default entites (<>&"')
-            if ((s = root->ent[i + 1]) < root->tmp_start || s > root->tmp_end) {
-               V3_Free(s);
-           }
-       }
-
-       V3_Free(root->ent); // free list of general entities
-
-        for (i = 0; (a = root->attr[i]); i++) {
-            for (j = 1; a[j++]; j += 2) {
-               // free malloced attribute values
-                if (a[j] && (a[j] < root->tmp_start || a[j] > root->tmp_end)) {
-                   V3_Free(a[j]);
-               }
-           }
-            V3_Free(a);
-        }
-
-        if (root->attr[0]) {
-           // free default attribute list
-           V3_Free(root->attr);
-       }
-
        V3_Free(root->str_ptr); // malloced xml data
     }
 
     v3_xml_free_attr(xml->attr); // tag attributes
 
+
+
     if ((xml->flags & V3_XML_TXTM)) {
        // character content
        V3_Free(xml->txt); 
@@ -908,6 +778,9 @@ void v3_xml_free(struct v3_xml * xml) {
 
 
 
+/* Adding XML data */
+
+
 
 
 // sets the character content for the given tag and returns the tag
@@ -1129,8 +1002,8 @@ static char *ampencode(const char *s, size_t len, char **dst, size_t *dlen,
 // its length excedes max. start is the location of the previous tag in the
 // parent tag's character content. Returns *s.
 static char *toxml_r(struct v3_xml * xml, char **s, size_t *len, size_t *max,
-                    size_t start, char ***attr) {
-    int i, j;
+                    size_t start) {
+    int i;
     char *txt = (xml->parent) ? xml->parent->txt : "";
     size_t off = 0;
 
@@ -1158,23 +1031,10 @@ static char *toxml_r(struct v3_xml * xml, char **s, size_t *len, size_t *max,
         *len += sprintf(*s + *len, "\"");
     }
 
-    for (i = 0; attr[i] && strcmp(attr[i][0], xml->name); i++);
-    for (j = 1; attr[i] && attr[i][j]; j += 3) { // default attributes
-        if (! attr[i][j + 1] || v3_xml_attr(xml, attr[i][j]) != attr[i][j + 1])
-            continue; // skip duplicates and non-values
-        while (*len + strlen(attr[i][j]) + 7 > *max) {
-           // reallocate s
-            *s = tmp_realloc(*s, *max, *max + V3_XML_BUFSIZE);
-           *max += V3_XML_BUFSIZE;
-       }
-
-        *len += sprintf(*s + *len, " %s=\"", attr[i][j]);
-        ampencode(attr[i][j + 1], -1, s, len, max, 1);
-        *len += sprintf(*s + *len, "\"");
-    }
+  
     *len += sprintf(*s + *len, ">");
 
-    *s = (xml->child) ? toxml_r(xml->child, s, len, max, 0, attr) //child
+    *s = (xml->child) ? toxml_r(xml->child, s, len, max, 0) //child
                       : ampencode(xml->txt, -1, s, len, max, 0);  //data
     
     while (*len + strlen(xml->name) + 4 > *max) {
@@ -1186,7 +1046,7 @@ static char *toxml_r(struct v3_xml * xml, char **s, size_t *len, size_t *max,
     *len += sprintf(*s + *len, "</%s>", xml->name); // close tag
 
     while (txt[off] && off < xml->off) off++; // make sure off is within bounds
-    return (xml->ordered) ? toxml_r(xml->ordered, s, len, max, off, attr)
+    return (xml->ordered) ? toxml_r(xml->ordered, s, len, max, off)
                           : ampencode(txt + off, -1, s, len, max, 0);
 }
 
@@ -1204,7 +1064,7 @@ char * v3_xml_tostr(struct v3_xml * xml) {
 
 
     xml->parent = xml->ordered = NULL;
-    s = toxml_r(xml, &s, &len, &max, 0, root->attr);
+    s = toxml_r(xml, &s, &len, &max, 0);
     xml->parent = p;
     xml->ordered = o;
 
index c7728a5..03dab64 100644 (file)
@@ -549,7 +549,7 @@ int v3_deinit_vmx_vmcs(struct guest_info * core) {
     struct vmx_data * vmx_state = core->vmm_data;
 
     V3_FreePages((void *)(vmx_state->vmcs_ptr_phys), 1);
-    V3_FreePages(vmx_state->msr_area, 1);
+    V3_FreePages(V3_PAddr(vmx_state->msr_area), 1);
 
     V3_Free(vmx_state);
 
@@ -1018,6 +1018,7 @@ int v3_reset_vmx_vm_core(struct guest_info * core, addr_t rip) {
 
 
 void v3_init_vmx_cpu(int cpu_id) {
+    addr_t vmx_on_region = 0;
 
     if (cpu_id == 0) {
        if (v3_init_vmx_hw(&hw_info) == -1) {
@@ -1030,17 +1031,18 @@ void v3_init_vmx_cpu(int cpu_id) {
 
 
     // Setup VMXON Region
-    host_vmcs_ptrs[cpu_id] = allocate_vmcs();
+    vmx_on_region = allocate_vmcs();
 
-    PrintDebug("VMXON pointer: 0x%p\n", (void *)host_vmcs_ptrs[cpu_id]);
 
-    if (vmx_on(host_vmcs_ptrs[cpu_id]) == VMX_SUCCESS) {
+    if (vmx_on(vmx_on_region) == VMX_SUCCESS) {
         V3_Print("VMX Enabled\n");
+       host_vmcs_ptrs[cpu_id] = vmx_on_region;
     } else {
-        PrintError("VMX initialization failure\n");
-        return;
+        V3_Print("VMX already enabled\n");
+       V3_FreePages((void *)vmx_on_region, 1);
     }
-    
+
+    PrintDebug("VMXON pointer: 0x%p\n", (void *)host_vmcs_ptrs[cpu_id]);    
 
     {
        struct vmx_sec_proc_ctrls sec_proc_ctrls;
@@ -1063,5 +1065,16 @@ void v3_init_vmx_cpu(int cpu_id) {
 void v3_deinit_vmx_cpu(int cpu_id) {
     extern v3_cpu_arch_t v3_cpu_types[];
     v3_cpu_types[cpu_id] = V3_INVALID_CPU;
-    V3_FreePages((void *)host_vmcs_ptrs[cpu_id], 1);
+
+    if (host_vmcs_ptrs[cpu_id] != 0) {
+       V3_Print("Disabling VMX\n");
+
+       if (vmx_off() != VMX_SUCCESS) {
+           PrintError("Error executing VMXOFF\n");
+       }
+
+       V3_FreePages((void *)host_vmcs_ptrs[cpu_id], 1);
+
+       host_vmcs_ptrs[cpu_id] = 0;
+    }
 }