From: Lei Xia Date: Thu, 1 Sep 2011 15:30:07 +0000 (-0500) Subject: Merge branch 'devel' of palacios@newskysaw.cs.northwestern.edu:/home/palacios/palacio... X-Git-Url: http://v3vee.org/palacios/gitweb/gitweb.cgi?a=commitdiff_plain;h=a489c2ba0f26f4be1fa98d4af2c2bfa113c28dde;hp=5c16780e3eb5e4ef59de8e929e2528bb07fce5ec;p=palacios.git Merge branch 'devel' of palacios@newskysaw.cs.northwestern.edu:/home/palacios/palacios into devel --- diff --git a/linux_module/mm.c b/linux_module/mm.c index a62b55a..04dcab3 100644 --- a/linux_module/mm.c +++ b/linux_module/mm.c @@ -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) { diff --git a/linux_module/palacios-stubs.c b/linux_module/palacios-stubs.c index 31fcdbf..36f7625 100644 --- a/linux_module/palacios-stubs.c +++ b/linux_module/palacios-stubs.c @@ -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; diff --git a/linux_module/vm.c b/linux_module/vm.c index 1702ffa..f53a598 100644 --- a/linux_module/vm.c +++ b/linux_module/vm.c @@ -12,7 +12,7 @@ #include #include #include - +#include #include #include #include @@ -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 index 0000000..3b9e192 --- /dev/null +++ b/linux_usr/v3_cons_sc.c @@ -0,0 +1,618 @@ +/* + * V3 Console utility + * Taken from Palacios console display in MINIX ( by Erik Van der Kouwe ) + * (c) Jack lange, 2010 + */ + + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#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 \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; +} + + diff --git a/linux_usr/v3_mem.c b/linux_usr/v3_mem.c index e51ef18..b02cdeb 100644 --- a/linux_usr/v3_mem.c +++ b/linux_usr/v3_mem.c @@ -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 \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 */ diff --git a/palacios/src/palacios/vmm.c b/palacios/src/palacios/vmm.c index 317f219..34b6c2c 100644 --- a/palacios/src/palacios/vmm.c +++ b/palacios/src/palacios/vmm.c @@ -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); } } } diff --git a/palacios/src/palacios/vmm_string.c b/palacios/src/palacios/vmm_string.c index 725fa17..75a8975 100644 --- a/palacios/src/palacios/vmm_string.c +++ b/palacios/src/palacios/vmm_string.c @@ -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; diff --git a/palacios/src/palacios/vmm_xml.c b/palacios/src/palacios/vmm_xml.c index d6963c8..d09a176 100644 --- a/palacios/src/palacios/vmm_xml.c +++ b/palacios/src/palacios/vmm_xml.c @@ -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 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;", "<", "gt;", ">", "quot;", """, - "apos;", "'", "amp;", "&", 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, "", 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; diff --git a/palacios/src/palacios/vmx.c b/palacios/src/palacios/vmx.c index c7728a5..03dab64 100644 --- a/palacios/src/palacios/vmx.c +++ b/palacios/src/palacios/vmx.c @@ -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; + } }