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) {
addr = kmalloc(size, GFP_KERNEL);
}
mallocs++;
+
return addr;
}
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;
#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>
cdev_del(&(guest->cdev));
- kfree(guest->img);
+ vfree(guest->img);
kfree(guest);
return 0;
--- /dev/null
+/*
+ * 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;
+}
+
+
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");
}
+ 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 */
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);
}
}
}
for (i = 0; i < reject_len; i++) {
if (s[cnt] == reject[i]) {
match = 1;
- cnt++;
break;
}
}
+
+ if (!match) {
+ cnt++;
+ }
+
}
return cnt;
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
};
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;
// 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;
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
// 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++) {
*(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++) = ' ';
}
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
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) {
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);
}
// 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));
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;
}
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;
*(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)
(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));
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
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 "=");
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], ' ');
}
}
*buf = '\0';
tag_ptr = ++buf;
+ /* Eat leading whitespace */
+ while (*buf && isspace(*buf)) {
+ buf++;
+ }
+
if (*buf && (*buf != '<')) {
// tag character content
while (*buf && (*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;
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);
+/* Adding XML data */
+
+
// sets the character content for the given tag and returns the tag
// 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;
*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) {
*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);
}
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;
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);
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) {
// 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;
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;
+ }
}