From: Peter Dinda Date: Wed, 27 Jun 2012 19:20:45 +0000 (-0500) Subject: Extensive, Pedantic Error Checking in Linux module, especially for memory X-Git-Url: http://v3vee.org/palacios/gitweb/gitweb.cgi?a=commitdiff_plain;h=07aa8f3c18a33af0961e7546980a63ab5f6fba4f;p=palacios.releases.git Extensive, Pedantic Error Checking in Linux module, especially for memory --- diff --git a/linux_module/iface-code-inject.c b/linux_module/iface-code-inject.c index d0b5495..b36edd1 100644 --- a/linux_module/iface-code-inject.c +++ b/linux_module/iface-code-inject.c @@ -43,8 +43,8 @@ static void free_inject_data (void) { for(i = 0; i < MAX_INJ; i++) { if (top_map[i]) { - kfree(top_map[i]->elf_data); - kfree(top_map[i]); + palacios_free(top_map[i]->elf_data); + palacios_free(top_map[i]); } } } @@ -55,7 +55,7 @@ static int vm_tophalf_inject (struct v3_guest * guest, unsigned int cmd, unsigne struct top_half_data top_arg; struct top_half_data * top; - top = kmalloc(sizeof(struct top_half_data), GFP_KERNEL); + top = palacios_alloc(sizeof(struct top_half_data)); if (IS_ERR(top)) { ERROR("Palacios Error: could not allocate space for top half data\n"); return -EFAULT; @@ -65,6 +65,7 @@ static int vm_tophalf_inject (struct v3_guest * guest, unsigned int cmd, unsigne INFO("Palacios: Loading ELF data...\n"); if (copy_from_user(&top_arg, (void __user *)arg, sizeof(struct top_half_data))) { ERROR("palacios: error copying ELF from userspace\n"); + palacios_free(top); return -EFAULT; } @@ -80,9 +81,10 @@ static int vm_tophalf_inject (struct v3_guest * guest, unsigned int cmd, unsigne } DEBUG("Palacios: Allocating %lu B of kernel memory for ELF binary data...\n", top->elf_size); - top->elf_data = kmalloc(top->elf_size, GFP_KERNEL); + top->elf_data = palacios_alloc(top->elf_size); if (IS_ERR(top->elf_data)) { ERROR("Palacios Error: could not allocate space for binary image\n"); + palacios_free(top); return -EFAULT; } memset(top->elf_data, 0, top->elf_size); @@ -90,16 +92,24 @@ static int vm_tophalf_inject (struct v3_guest * guest, unsigned int cmd, unsigne INFO("Palacios: Copying ELF image into kernel module...\n"); if (copy_from_user(top->elf_data, (void __user *)top_arg.elf_data, top->elf_size)) { ERROR("Palacios: Error loading elf data\n"); + palacios_free(top->elf_data); + palacios_free(top); return -EFAULT; } - if (register_top(top) < 0) + if (register_top(top) < 0) { + ERROR("Cannot register top half\n"); + palacios_free(top->elf_data); + palacios_free(top); return -1; - + } + INFO("Palacios: setting up inject code...\n"); if (v3_insert_code_inject(guest->v3_ctx, top->elf_data, top->elf_size, top->bin_file, top->is_dyn, top->is_exec_hooked, top->func_offset) < 0) { ERROR("Palacios Error: error setting up inject code\n"); + palacios_free(top->elf_data); + palacios_free(top); return -1; } diff --git a/linux_module/iface-console.c b/linux_module/iface-console.c index c28fd4c..a11c50e 100644 --- a/linux_module/iface-console.c +++ b/linux_module/iface-console.c @@ -113,7 +113,7 @@ console_read(struct file * filp, char __user * buf, size_t size, loff_t * offset } - kfree(msg); + palacios_free(msg); spin_lock_irqsave(&(cons->queue->lock), flags); entries = cons->queue->num_entries; @@ -188,7 +188,7 @@ static int console_release(struct inode * i, struct file * filp) { spin_unlock_irqrestore(&(cons->queue->lock), flags); while ((msg = dequeue(cons->queue))) { - kfree(msg); + palacios_free(msg); } return 0; @@ -247,17 +247,24 @@ static int console_connect(struct v3_guest * guest, unsigned int cmd, static void * palacios_tty_open(void * private_data, unsigned int width, unsigned int height) { struct v3_guest * guest = (struct v3_guest *)private_data; - struct palacios_console * cons = kmalloc(sizeof(struct palacios_console), GFP_KERNEL); + struct palacios_console * cons = palacios_alloc(sizeof(struct palacios_console)); + + if (!cons) { + ERROR("Cannot allocate memory for console\n"); + return NULL; + } INFO("Guest initialized virtual console (Guest=%s)\n", guest->name); if (guest == NULL) { ERROR("ERROR: Cannot open a console on a NULL guest\n"); + palacios_free(cons); return NULL; } if (cons->open == 1) { ERROR("Console already open\n"); + palacios_free(cons); return NULL; } @@ -301,7 +308,12 @@ static int palacios_tty_cursor_set(void * console, int x, int y) { return 0; } - msg = kmalloc(sizeof(struct cons_msg), GFP_KERNEL); + msg = palacios_alloc(sizeof(struct cons_msg)); + + if (!msg) { + ERROR("Cannot allocate cursor set message in console\n"); + return -1; + } msg->op = CONSOLE_CURS_SET; msg->cursor.x = x; @@ -318,7 +330,12 @@ static int palacios_tty_character_set(void * console, int x, int y, char c, unsi return 0; } - msg = kmalloc(sizeof(struct cons_msg), GFP_KERNEL); + msg = palacios_alloc(sizeof(struct cons_msg)); + + if (!msg) { + ERROR("Cannot allocate character set message in console\n"); + return -1; + } msg->op = CONSOLE_CHAR_SET; msg->character.x = x; @@ -338,7 +355,12 @@ static int palacios_tty_scroll(void * console, int lines) { return 0; } - msg = kmalloc(sizeof(struct cons_msg), GFP_KERNEL); + msg = palacios_alloc(sizeof(struct cons_msg)); + + if (!msg) { + ERROR("Cannot allocate scroll message in console\n"); + return -1; + } msg->op = CONSOLE_SCROLL; msg->scroll.lines = lines; @@ -354,7 +376,12 @@ static int palacios_set_text_resolution(void * console, int cols, int rows) { return 0; } - msg = kmalloc(sizeof(struct cons_msg), GFP_KERNEL); + msg = palacios_alloc(sizeof(struct cons_msg)); + + if (!msg) { + ERROR("Cannot allocate text resolution message in console\n"); + return -1; + } msg->op = CONSOLE_RESOLUTION; msg->resolution.cols = cols; @@ -371,7 +398,12 @@ static int palacios_tty_update(void * console) { return 0; } - msg = kmalloc(sizeof(struct cons_msg), GFP_KERNEL); + msg = palacios_alloc(sizeof(struct cons_msg)); + + if (!msg) { + ERROR("Cannot allocate update message in console\n"); + return -1; + } msg->op = CONSOLE_UPDATE; diff --git a/linux_module/iface-env-inject.c b/linux_module/iface-env-inject.c index 7fcc652..af8e5de 100644 --- a/linux_module/iface-env-inject.c +++ b/linux_module/iface-env-inject.c @@ -37,11 +37,11 @@ static void free_inject_data (void) { for(i = 0; i < MAX_ENV_INJECT; i++) { if (env_map[i]) { - for (j = 0; j < env_map[i]->num_strings; j++) - kfree(env_map[i]->strings[j]); - - kfree(env_map[i]->strings); - kfree(env_map[i]); + for (j = 0; j < env_map[i]->num_strings; j++) { + palacios_free(env_map[i]->strings[j]); + } + palacios_free(env_map[i]->strings); + palacios_free(env_map[i]); } } } @@ -59,7 +59,7 @@ static int vm_env_inject (struct v3_guest * guest, unsigned int cmd, unsigned lo return -EFAULT; } - env = kmalloc(sizeof(struct env_data), GFP_KERNEL); + env = palacios_alloc(sizeof(struct env_data)); if (IS_ERR(env)) { ERROR("Palacios Error: could not allocate space for environment data\n"); return -EFAULT; @@ -73,7 +73,7 @@ static int vm_env_inject (struct v3_guest * guest, unsigned int cmd, unsigned lo DEBUG("Binary hooked on: %s\n", env->bin_name); //DEBUG("Palacios: Allocating space for %u env var string ptrs...\n", env->num_strings); - env->strings = kmalloc(env->num_strings*sizeof(char*), GFP_KERNEL); + env->strings = palacios_alloc(env->num_strings*sizeof(char*)); if (IS_ERR(env->strings)) { ERROR("Palacios Error: could not allocate space for env var strings\n"); return -EFAULT; @@ -87,7 +87,7 @@ static int vm_env_inject (struct v3_guest * guest, unsigned int cmd, unsigned lo } for (i = 0; i < env->num_strings; i++) { - char * tmp = kmalloc(MAX_STRING_LEN, GFP_KERNEL); + char * tmp = palacios_alloc(MAX_STRING_LEN); if (IS_ERR(tmp)) { ERROR("Palacios Error: could not allocate space for env var string #%d\n", i); return -EFAULT; diff --git a/linux_module/iface-file.c b/linux_module/iface-file.c index 062a6d2..46d4a28 100644 --- a/linux_module/iface-file.c +++ b/linux_module/iface-file.c @@ -49,7 +49,12 @@ static int mkdir_recursive(const char * path, unsigned short perms) { char * dirname_ptr; char * tmp_iter; - tmp_str = kmalloc(strlen(path) + 1, GFP_KERNEL); + tmp_str = palacios_alloc(strlen(path) + 1); + if (!tmp_str) { + ERROR("Cannot allocate in mkdir recursive\n"); + return -1; + } + memset(tmp_str, 0, strlen(path) + 1); strncpy(tmp_str, path, strlen(path)); @@ -67,6 +72,7 @@ static int mkdir_recursive(const char * path, unsigned short perms) { if ( (!isprint(*tmp_iter))) { ERROR("Invalid character in path name (%d)\n", *tmp_iter); + palacios_free(tmp_str); return -1; } else { tmp_iter++; @@ -83,6 +89,7 @@ static int mkdir_recursive(const char * path, unsigned short perms) { if ((tmp_iter - dirname_ptr) > 1) { if (palacios_file_mkdir(tmp_str, perms, 0) != 0) { ERROR("Could not create directory (%s)\n", tmp_str); + palacios_free(tmp_str); return -1; } } @@ -98,7 +105,7 @@ static int mkdir_recursive(const char * path, unsigned short perms) { dirname_ptr = tmp_iter; } - kfree(tmp_str); + palacios_free(tmp_str); return 0; } @@ -188,7 +195,11 @@ static void * palacios_file_open(const char * path, int mode, void * private_dat } } - pfile = kmalloc(sizeof(struct palacios_file), GFP_KERNEL); + pfile = palacios_alloc(sizeof(struct palacios_file)); + if (!pfile) { + ERROR("Cannot allocate in file open\n"); + return NULL; + } memset(pfile, 0, sizeof(struct palacios_file)); if ((mode & FILE_OPEN_MODE_READ) && (mode & FILE_OPEN_MODE_WRITE)) { @@ -211,10 +222,18 @@ static void * palacios_file_open(const char * path, int mode, void * private_dat if (IS_ERR(pfile->filp)) { ERROR("Cannot open file: %s\n", path); + palacios_free(pfile); return NULL; } - pfile->path = kmalloc(strlen(path) + 1, GFP_KERNEL); + pfile->path = palacios_alloc(strlen(path)); + + if (!pfile->path) { + ERROR("Cannot allocate in file open\n"); + filp_close(pfile->filp,NULL); + palacios_free(pfile); + return NULL; + } strncpy(pfile->path, path, strlen(path)); pfile->guest = guest; @@ -237,8 +256,8 @@ static int palacios_file_close(void * file_ptr) { list_del(&(pfile->file_node)); - kfree(pfile->path); - kfree(pfile); + palacios_free(pfile->path); + palacios_free(pfile); return 0; } @@ -331,7 +350,13 @@ static int file_deinit( void ) { } static int guest_file_init(struct v3_guest * guest, void ** vm_data) { - struct vm_file_state * state = kmalloc(sizeof(struct vm_file_state), GFP_KERNEL); + struct vm_file_state * state = palacios_alloc(sizeof(struct vm_file_state)); + + if (!state) { + ERROR("Cannot allocate when intializing file services for guest\n"); + return -1; + } + INIT_LIST_HEAD(&(state->open_files)); @@ -344,7 +369,8 @@ static int guest_file_init(struct v3_guest * guest, void ** vm_data) { static int guest_file_deinit(struct v3_guest * guest, void * vm_data) { - kfree(vm_data); + palacios_free(vm_data); + return 0; } diff --git a/linux_module/iface-graphics-console.c b/linux_module/iface-graphics-console.c index 07d979b..d05510a 100644 --- a/linux_module/iface-graphics-console.c +++ b/linux_module/iface-graphics-console.c @@ -41,6 +41,7 @@ */ +static struct list_head global_gcons; struct palacios_graphics_console { // descriptor for the data in the shared frame buffer @@ -62,10 +63,12 @@ struct palacios_graphics_console { void *priv_data); void *render_data; - int (*update_inquire)(v3_graphics_console_t cons, - void *priv_data); - - void *update_data; + int (*update_inquire)(v3_graphics_console_t cons, + void *priv_data); + + void *update_data; + + struct list_head gcons_node; }; @@ -146,7 +149,7 @@ static void g_close(v3_graphics_console_t cons) return; } if (gc->data) { - kfree(gc->data); + vfree(gc->data); gc->data=0; } } @@ -297,12 +300,23 @@ static struct v3_graphics_console_hooks palacios_graphics_console_hooks = static int graphics_console_init( void ) { + INIT_LIST_HEAD(&(global_gcons)); + V3_Init_Graphics_Console(&palacios_graphics_console_hooks); return 0; } +static int graphics_console_deinit( void ) { + + if (!list_empty(&global_gcons)) { + ERROR("Removing graphics console with open consoles - MEMORY LEAK\n"); + } + + return 0; +} + static int fb_query(struct v3_guest * guest, unsigned int cmd, unsigned long arg, void * priv_data) { @@ -425,7 +439,7 @@ static int fb_input(struct v3_guest * guest, static int graphics_console_guest_init(struct v3_guest * guest, void ** vm_data) { - struct palacios_graphics_console * graphics_cons = kmalloc(sizeof(struct palacios_graphics_console), GFP_KERNEL); + struct palacios_graphics_console * graphics_cons = palacios_alloc(sizeof(struct palacios_graphics_console)); if (!graphics_cons) { ERROR("palacios: filed to do guest_init for graphics console\n"); @@ -439,17 +453,34 @@ static int graphics_console_guest_init(struct v3_guest * guest, void ** vm_data) add_guest_ctrl(guest, V3_VM_FB_INPUT, fb_input, graphics_cons); add_guest_ctrl(guest, V3_VM_FB_QUERY, fb_query, graphics_cons); + list_add(&(graphics_cons->gcons_node),&global_gcons); + return 0; } +static int graphics_console_guest_deinit(struct v3_guest * guest, void * vm_data) { + struct palacios_graphics_console * graphics_cons = (struct palacios_graphics_console *)vm_data; + + list_del(&(graphics_cons->gcons_node)); + + if (graphics_cons->data) { + vfree(graphics_cons->data); + } + + palacios_free(graphics_cons); + + return 0; +} + + static struct linux_ext graphics_cons_ext = { .name = "GRAPHICS_CONSOLE_INTERFACE", .init = graphics_console_init, - .deinit = NULL, + .deinit = graphics_console_deinit, .guest_init = graphics_console_guest_init, - .guest_deinit = NULL + .guest_deinit = graphics_console_guest_deinit, }; diff --git a/linux_module/iface-host-dev.c b/linux_module/iface-host-dev.c index 5ef4d16..a622029 100644 --- a/linux_module/iface-host-dev.c +++ b/linux_module/iface-host-dev.c @@ -138,9 +138,6 @@ struct palacios_host_dev { #define SHALLOW_DEBUG_PRINT(fmt, args...) #endif -// Moved to palacios.h -//define ERROR(fmt, args...) -//define INFO(fmt, args...) struct palacios_host_device_user { spinlock_t lock; @@ -171,14 +168,14 @@ struct palacios_host_device_user { static void palacios_host_dev_user_free(struct palacios_host_device_user *dev) { if (dev->req) { - kfree(dev->req); + palacios_free(dev->req); dev->req=0; } if (dev->resp) { - kfree(dev->resp); + palacios_free(dev->resp); dev->resp=0; } - kfree(dev); + palacios_free(dev); } @@ -216,8 +213,8 @@ static int palacios_resize_reqresp(struct palacios_host_dev_host_request_respons if ((*r)==0) { // allocate it DEEP_DEBUG_PRINT("palacios: hostdev: attempt alloc\n"); - *r = kmalloc(sizeof(struct palacios_host_dev_host_request_response)+data_size,GFP_KERNEL); - DEEP_DEBUG_PRINT("palacios: hostdev: kmalloc done\n"); + *r = palacios_alloc(sizeof(struct palacios_host_dev_host_request_response)+data_size); + DEEP_DEBUG_PRINT("palacios: hostdev: palacios_alloc done\n"); if ((*r)==0) { ERROR("palacios: hostdev: failed to allocate\n"); return -1; @@ -238,10 +235,10 @@ static int palacios_resize_reqresp(struct palacios_host_dev_host_request_respons struct palacios_host_dev_host_request_response *new; if (!copy) { - kfree(*r); + palacios_free(*r); *r=0; } - new = kmalloc(sizeof(struct palacios_host_dev_host_request_response)+data_size,GFP_KERNEL); + new = palacios_alloc(sizeof(struct palacios_host_dev_host_request_response)+data_size); if (!new) { ERROR("palacios: hostdev: failed to reallocate\n"); return -1; @@ -250,7 +247,7 @@ static int palacios_resize_reqresp(struct palacios_host_dev_host_request_respons if (copy) { memcpy(new->data,(*r)->data,(*r)->data_len-sizeof(struct palacios_host_dev_host_request_response)); new->data_len=(*r)->data_len; - kfree(*r); + palacios_free(*r); } *r=new; DEEP_DEBUG_PRINT("palacios: hostdev: reallocated\n"); @@ -370,7 +367,7 @@ static long host_dev_ioctl(struct file * fp, unsigned int val, unsigned long arg switch (op.type) { case PALACIOS_HOST_DEV_USER_REQUEST_READ_GUEST: { - void *temp = kmalloc(op.len,GFP_KERNEL); + void *temp = palacios_alloc(op.len); DEEP_DEBUG_PRINT("palacios: hostdev: read guest\n"); @@ -385,17 +382,17 @@ static long host_dev_ioctl(struct file * fp, unsigned int val, unsigned long arg temp, op.len) != op.len) { ERROR("palacios: unable to read enough from guest for host device \"%s\"\n",dev->url); - kfree(temp); + palacios_free(temp); return -EFAULT; } if (copy_to_user(op.data,temp,op.len)) { ERROR("palacios: unable to copy to user for host device \"%s\"\n",dev->url); - kfree(temp); + palacios_free(temp); return -EFAULT; } - kfree(temp); + palacios_free(temp); return op.len; } @@ -407,7 +404,7 @@ static long host_dev_ioctl(struct file * fp, unsigned int val, unsigned long arg DEEP_DEBUG_PRINT("palacios: hostdev: write guest\n"); - temp = kmalloc(op.len,GFP_KERNEL); + temp = palacios_alloc(op.len); if (!temp) { ERROR("palacios: unable to allocate enough for write guest request for host device \"%s\"\n",dev->url); @@ -416,7 +413,7 @@ static long host_dev_ioctl(struct file * fp, unsigned int val, unsigned long arg if (copy_from_user(temp,op.data,op.len)) { ERROR("palacios: unable to copy from user for host device \"%s\"\n",dev->url); - kfree(temp); + palacios_free(temp); return -EFAULT; } @@ -426,11 +423,11 @@ static long host_dev_ioctl(struct file * fp, unsigned int val, unsigned long arg temp, op.len) != op.len) { ERROR("palacios: unable to write enough to guest for host device \"%s\"\n",dev->url); - kfree(temp); + palacios_free(temp); return -EFAULT; } - kfree(temp); + palacios_free(temp); return op.len; } @@ -653,11 +650,11 @@ static int host_dev_connect(struct v3_guest * guest, unsigned int cmd, unsigned dev->connected=1; dev->waiting=0; if (dev->req) { - kfree(dev->req); + palacios_free(dev->req); dev->req=0; } if (dev->resp) { - kfree(dev->resp); + palacios_free(dev->resp); dev->resp=0; } INFO("palacios: connected fd for device \"%s\"\n",url); @@ -775,7 +772,7 @@ static v3_host_dev_t palacios_host_dev_open_deferred(char *url, INFO("palacios: creating host device \"%s\"\n",url); - dev = kmalloc(sizeof(struct palacios_host_device_user),GFP_KERNEL); + dev = palacios_alloc(sizeof(struct palacios_host_device_user)); if (!dev) { ERROR("palacios: cannot allocate for host device \"%s\"\n",url); @@ -1324,7 +1321,7 @@ static int host_dev_init( void ) { static int host_dev_guest_init(struct v3_guest * guest, void ** vm_data ) { - struct palacios_host_dev * host_dev = kmalloc(sizeof(struct palacios_host_dev), GFP_KERNEL); + struct palacios_host_dev * host_dev = palacios_alloc(sizeof(struct palacios_host_dev)); if (!host_dev) { ERROR("palacios: failed to do guest_init for host device\n"); diff --git a/linux_module/iface-keyed-stream.c b/linux_module/iface-keyed-stream.c index 68445d4..41da2fb 100644 --- a/linux_module/iface-keyed-stream.c +++ b/linux_module/iface-keyed-stream.c @@ -120,7 +120,7 @@ struct mem_stream { static struct mem_stream *create_mem_stream_internal(uint64_t size) { - struct mem_stream *m = kmalloc(sizeof(struct mem_stream),GFP_KERNEL); + struct mem_stream *m = palacios_alloc(sizeof(struct mem_stream)); if (!m) { return 0; @@ -130,7 +130,7 @@ static struct mem_stream *create_mem_stream_internal(uint64_t size) m->data = vmalloc(size); if (!m->data) { - kfree(m); + palacios_free(m); return 0; } @@ -152,10 +152,10 @@ static void destroy_mem_stream(struct mem_stream *m) { if (m) { if (m->data) { - kfree(m->data); + vfree(m->data); } m->data=0; - kfree(m); + palacios_free(m); } } @@ -172,7 +172,7 @@ static int expand_mem_stream(struct mem_stream *m, uint32_t new_size) memcpy(data,m->data,nc); - kfree(m->data); + vfree(m->data); m->data=data; m->size=new_size; @@ -261,7 +261,7 @@ static v3_keyed_stream_t open_stream_mem(char *url, if (!mks) { char *mykey; - mykey = kmalloc(strlen(url+4)+1,GFP_KERNEL); + mykey = palacios_alloc(strlen(url+4)+1); if (!mykey) { ERROR("cannot allocate space for new in-memory keyed stream %s\n",url); @@ -270,18 +270,18 @@ static v3_keyed_stream_t open_stream_mem(char *url, strcpy(mykey,url+4); - mks = (struct mem_keyed_stream *) kmalloc(sizeof(struct mem_keyed_stream),GFP_KERNEL); + mks = (struct mem_keyed_stream *) palacios_alloc(sizeof(struct mem_keyed_stream)); if (!mks) { - kfree(mykey); + palacios_free(mykey); ERROR("cannot allocate in-memory keyed stream %s\n",url); return 0; } mks->ht = (void*) palacios_create_htable(DEF_NUM_KEYS,hash_func,hash_comp); if (!mks->ht) { - kfree(mks); - kfree(mykey); + palacios_free(mks); + palacios_free(mykey); ERROR("cannot allocate in-memory keyed stream %s\n",url); return 0; } @@ -289,8 +289,8 @@ static v3_keyed_stream_t open_stream_mem(char *url, if (!palacios_htable_insert(mem_streams,(addr_t)(mykey),(addr_t)mks)) { palacios_free_htable(mks->ht,1,1); - kfree(mks); - kfree(mykey); + palacios_free(mks); + palacios_free(mykey); ERROR("cannot insert in-memory keyed stream %s\n",url); return 0; } @@ -333,7 +333,7 @@ static v3_keyed_stream_key_t open_key_mem(v3_keyed_stream_t stream, m = (struct mem_stream *) palacios_htable_search(s,(addr_t)key); if (!m) { - char *mykey = kmalloc(strlen(key)+1,GFP_KERNEL); + char *mykey = palacios_alloc(strlen(key)+1); if (!mykey) { ERROR("cannot allocate copy of key for key %s\n",key); @@ -345,14 +345,14 @@ static v3_keyed_stream_key_t open_key_mem(v3_keyed_stream_t stream, m = create_mem_stream(); if (!m) { - kfree(mykey); + palacios_free(mykey); ERROR("cannot allocate mem keyed stream for key %s\n",key); return 0; } if (!palacios_htable_insert(s,(addr_t)mykey,(addr_t)m)) { destroy_mem_stream(m); - kfree(mykey); + palacios_free(mykey); ERROR("cannot insert mem keyed stream for key %s\n",key); return 0; } @@ -382,7 +382,7 @@ static void preallocate_hint_key_mem(v3_keyed_stream_t stream, if (!m) { char *mykey; - mykey=kmalloc(strlen(key)+1,GFP_KERNEL); + mykey=palacios_alloc(strlen(key)+1); if (!mykey) { ERROR("cannot allocate key space for preallocte for key %s\n",key); @@ -516,18 +516,18 @@ static v3_keyed_stream_t open_stream_file(char *url, return 0; } - fks = kmalloc(sizeof(struct file_keyed_stream),GFP_KERNEL); + fks = palacios_alloc(sizeof(struct file_keyed_stream)); if (!fks) { ERROR("cannot allocate space for file stream\n"); return 0; } - fks->path = (char*)kmalloc(strlen(url+5)+1,GFP_KERNEL); + fks->path = (char*)palacios_alloc(strlen(url+5)+1); if (!(fks->path)) { ERROR("cannot allocate space for file stream\n"); - kfree(fks); + palacios_free(fks); return 0; } @@ -607,8 +607,8 @@ static v3_keyed_stream_t open_stream_file(char *url, fail_out: - kfree(fks->path); - kfree(fks); + palacios_free(fks->path); + palacios_free(fks); return 0; } @@ -617,8 +617,8 @@ static void close_stream_file(v3_keyed_stream_t stream) { struct file_keyed_stream *fks = (struct file_keyed_stream *) stream; - kfree(fks->path); - kfree(fks); + palacios_free(fks->path); + palacios_free(fks); } @@ -638,7 +638,7 @@ static v3_keyed_stream_key_t open_key_file(v3_keyed_stream_t stream, // the path is the stream's path plus the key name // file:/home/foo + "regext" => "/home/foo/regext" - path = (char *) kmalloc(strlen(fks->path)+strlen(key)+2,GFP_KERNEL); + path = (char *) palacios_alloc(strlen(fks->path)+strlen(key)+2); if (!path) { ERROR("cannot allocate file keyed stream for key %s\n",key); return 0; @@ -647,11 +647,11 @@ static v3_keyed_stream_key_t open_key_file(v3_keyed_stream_t stream, strcat(path,"/"); strcat(path,key); - fs = (struct file_stream *) kmalloc(sizeof(struct file_stream *),GFP_KERNEL); + fs = (struct file_stream *) palacios_alloc(sizeof(struct file_stream *)); if (!fs) { ERROR("cannot allocate file keyed stream for key %s\n",key); - kfree(path); + palacios_free(path); return 0; } @@ -661,12 +661,12 @@ static v3_keyed_stream_key_t open_key_file(v3_keyed_stream_t stream, if (IS_ERR(fs->f)) { ERROR("cannot open relevent file \"%s\" for stream \"file:%s\" and key \"%s\"\n",path,fks->path,key); - kfree(fs); - kfree(path); + palacios_free(fs); + palacios_free(path); return 0; } - kfree(path); + palacios_free(path); return fs; } @@ -679,7 +679,7 @@ static void close_key_file(v3_keyed_stream_t stream, filp_close(fs->f,NULL); - kfree(fs); + palacios_free(fs); } static sint64_t write_key_file(v3_keyed_stream_t stream, @@ -805,7 +805,7 @@ static int resize_op(struct palacios_user_keyed_stream_op **op, uint64_t buf_len struct palacios_user_keyed_stream_op *new; if (!old) { - new = kmalloc(sizeof(struct palacios_user_keyed_stream_op)+buf_len,GFP_ATOMIC); + new = palacios_alloc(sizeof(struct palacios_user_keyed_stream_op)+buf_len); if (!new) { return -1; } else { @@ -819,7 +819,7 @@ static int resize_op(struct palacios_user_keyed_stream_op **op, uint64_t buf_len old->buf_len=buf_len; return 0; } else { - kfree(old); + palacios_free(old); *op = 0 ; return resize_op(op,buf_len); } @@ -1029,8 +1029,8 @@ static int keyed_stream_release_user(struct inode *inode, struct file *filp) spin_unlock_irqrestore(&(s->lock), f2); spin_unlock_irqrestore(&(user_streams->lock), f1); - kfree(s->url); - kfree(s); + palacios_free(s->url); + palacios_free(s); return 0; } @@ -1068,7 +1068,7 @@ int keyed_stream_connect_user(struct v3_guest *guest, unsigned int cmd, unsigned return -1; } - url = kmalloc(len,GFP_KERNEL); + url = palacios_alloc(len); if (!url) { ERROR("cannot allocate url for user keyed stream\n"); @@ -1087,18 +1087,18 @@ int keyed_stream_connect_user(struct v3_guest *guest, unsigned int cmd, unsigned list_for_each_entry(s, &(user_streams->streams), node) { if (!strncasecmp(url, s->url, len)) { ERROR("user keyed stream connection with url \"%s\" already exists\n", url); - kfree(url); + palacios_free(url); return -1; } } spin_unlock_irqrestore(&(user_streams->lock), flags); // Create connection - s = kmalloc(sizeof(struct user_keyed_stream), GFP_KERNEL); + s = palacios_alloc(sizeof(struct user_keyed_stream)); if (!s) { ERROR("cannot allocate new user keyed stream for %s\n",url); - kfree(url); + palacios_free(url); return -1; } @@ -1108,8 +1108,8 @@ int keyed_stream_connect_user(struct v3_guest *guest, unsigned int cmd, unsigned if (fd < 0) { ERROR("cannot allocate file descriptor for new user keyed stream for %s\n",url); - kfree(s); - kfree(url); + palacios_free(s); + palacios_free(url); return -1; } @@ -1388,7 +1388,7 @@ static struct net_stream * create_net_stream(void) { struct net_stream * ns = NULL; - ns = kmalloc(sizeof(struct net_stream), GFP_KERNEL); + ns = palacios_alloc(sizeof(struct net_stream)); if (!ns) { ERROR("Cannot allocate a net_stream\n"); @@ -1411,11 +1411,11 @@ static void close_socket(v3_keyed_stream_t stream) if (ns) { ns->sock->ops->release(ns->sock); - kfree(ns); + palacios_free(ns); ERROR("Close Socket\n"); } - kfree(ns); + palacios_free(ns); } } @@ -1601,7 +1601,7 @@ static struct net_stream * accept_once(struct net_stream * ns, const int port) // close the accept socket accept_sock->ops->release(accept_sock); - kfree(accept_sock); + palacios_free(accept_sock); return ns; } @@ -1618,7 +1618,7 @@ static struct v3_keyed_stream_t * open_stream_net(char * url,v3_keyed_stream_ope int ip_len; int port_len; - nks = kmalloc(sizeof(struct net_keyed_stream),GFP_KERNEL); + nks = palacios_alloc(sizeof(struct net_keyed_stream)); if (!nks) { ERROR("Could not allocate space in open_stream_net\n"); @@ -1633,7 +1633,7 @@ static struct v3_keyed_stream_t * open_stream_net(char * url,v3_keyed_stream_ope if (!(nks->ns)) { ERROR("Could not create network stream\n"); - kfree(nks); + palacios_free(nks); return 0; } @@ -1684,7 +1684,7 @@ static struct v3_keyed_stream_t * open_stream_net(char * url,v3_keyed_stream_ope connect_to_ip(nks->ns,host_ip, host_port); } else { ERROR("Mode not recognized\n"); - kfree(nks); + palacios_free(nks); return NULL; } @@ -2150,7 +2150,7 @@ static int init_keyed_streams( void ) return -1; } - user_streams = kmalloc(sizeof(struct user_keyed_streams),GFP_KERNEL); + user_streams = palacios_alloc(sizeof(struct user_keyed_streams)); if (!user_streams) { ERROR("failed to allocated list for user streams\n"); @@ -2171,7 +2171,7 @@ static int deinit_keyed_streams( void ) { palacios_free_htable(mem_streams,1,1); - kfree(user_streams); + palacios_free(user_streams); WARNING("Deinit of Palacios Keyed Streams likely leaked memory\n"); diff --git a/linux_module/iface-packet.c b/linux_module/iface-packet.c index 4cdec65..90a72bc 100644 --- a/linux_module/iface-packet.c +++ b/linux_module/iface-packet.c @@ -158,7 +158,12 @@ static int packet_recv_thread( void * arg ) { struct v3_packet * recver_state; struct raw_interface * iface = (struct raw_interface *)arg; - pkt = (unsigned char *)kmalloc(ETHERNET_PACKET_LEN, GFP_KERNEL); + pkt = (unsigned char *)palacios_alloc(ETHERNET_PACKET_LEN); + + if (!pkt) { + ERROR("Unable to allocate packet in vnet receive thread\n"); + return -1; + } INFO("Palacios Raw Packet Bridge: Staring receiving on ethernet device %s\n", iface->eth_dev); @@ -222,7 +227,7 @@ deinit_raw_interface(struct raw_interface * iface){ palacios_free_htable(iface->mac_to_recver, 0, 0); list_for_each_entry_safe(recver_state, tmp_state, &(iface->brdcast_recvers), node) { - kfree(recver_state); + palacios_free(recver_state); } } @@ -253,14 +258,14 @@ palacios_packet_connect(struct v3_packet * packet, spin_unlock_irqrestore(&(packet_state.lock),flags); if(iface == NULL){ - iface = (struct raw_interface *)kmalloc(sizeof(struct raw_interface), GFP_KERNEL); + iface = (struct raw_interface *)palacios_alloc(sizeof(struct raw_interface)); if (!iface) { - WARNING("Palacios Packet Interface: Fails to allocate interface\n"); + ERROR("Palacios Packet Interface: Fails to allocate interface\n"); return -1; } if(init_raw_interface(iface, host_nic) != 0) { - WARNING("Palacios Packet Interface: Fails to initiate an raw interface on device %s\n", host_nic); - kfree(iface); + ERROR("Palacios Packet Interface: Fails to initiate an raw interface on device %s\n", host_nic); + palacios_free(iface); return -1; } spin_lock_irqsave(&(packet_state.lock), flags); @@ -296,8 +301,7 @@ palacios_packet_send(struct v3_packet * packet, if(iface->inited == 0 || iface->raw_sock == NULL){ - WARNING("Palacios Packet Interface: Send fails due to inapproriate interface\n"); - + ERROR("Palacios Packet Interface: Send fails due to inapproriate interface\n"); return -1; } @@ -355,7 +359,7 @@ static int packet_deinit( void ) { list_for_each_entry_safe(iface, tmp, &(packet_state.open_interfaces), node) { deinit_raw_interface(iface); - kfree(iface); + palacios_free(iface); } return 0; diff --git a/linux_module/iface-socket.c b/linux_module/iface-socket.c index 39d18f0..82fbe56 100644 --- a/linux_module/iface-socket.c +++ b/linux_module/iface-socket.c @@ -57,13 +57,20 @@ palacios_tcp_socket(const int bufsize, const int nodelay, } - sock = kmalloc(sizeof(struct palacios_socket), GFP_KERNEL); + sock = palacios_alloc(sizeof(struct palacios_socket)); + + if (!sock) { + ERROR("Cannot allocate TCP socket\n"); + return NULL; + } + memset(sock, 0, sizeof(struct palacios_socket)); err = sock_create(PF_INET, SOCK_STREAM, IPPROTO_TCP, &(sock->sock)); if (err < 0) { - kfree(sock); + ERROR("Cannot create TCP socket\n"); + palacios_free(sock); return NULL; } @@ -101,13 +108,19 @@ palacios_udp_socket( } - sock = kmalloc(sizeof(struct palacios_socket), GFP_KERNEL); + sock = palacios_alloc(sizeof(struct palacios_socket)); + if (!sock) { + ERROR("Cannot allocate UDP socket\n"); + return NULL; + } + memset(sock, 0, sizeof(struct palacios_socket)); err = sock_create(AF_INET, SOCK_DGRAM, IPPROTO_UDP, &(sock->sock)) ; if (err < 0){ - kfree(sock); + ERROR("Cannot create UDP socket\n"); + palacios_free(sock); return NULL; } @@ -133,7 +146,7 @@ palacios_close(void * sock_ptr) sock->sock->ops->release(sock->sock); list_del(&(sock->sock_node)); - kfree(sock); + palacios_free(sock); } } @@ -193,12 +206,18 @@ static void * palacios_accept(const void * sock_ptr, unsigned int * remote_ip, u } - newsock = kmalloc(sizeof(struct palacios_socket), GFP_KERNEL); + newsock = palacios_alloc(sizeof(struct palacios_socket)); + + if (!newsock) { + ERROR("Cannot allocate new socket on accept\n"); + return NULL; + } err = sock_create(PF_INET, SOCK_STREAM, IPPROTO_TCP, &(newsock->sock)); if (err < 0) { - kfree(newsock); + ERROR("Cannot create new socket on accept\n"); + palacios_free(newsock); return NULL; } @@ -208,7 +227,8 @@ static void * palacios_accept(const void * sock_ptr, unsigned int * remote_ip, u err = newsock->sock->ops->accept(sock->sock, newsock->sock, 0); if (err < 0){ - kfree(newsock); + ERROR("Cannot accept\n"); + palacios_free(newsock); return NULL; } diff --git a/linux_module/iface-stream.c b/linux_module/iface-stream.c index 2463f56..62631fe 100644 --- a/linux_module/iface-stream.c +++ b/linux_module/iface-stream.c @@ -158,16 +158,22 @@ static ssize_t stream_write(struct file * filp, const char __user * buf, size_t char * kern_buf = NULL; ssize_t bytes_written = 0; - kern_buf = kmalloc(size, GFP_KERNEL); + kern_buf = palacios_alloc(size); + + if (!kern_buf) { + ERROR("Cannot allocate buffer in stream interface\n"); + return -EFAULT; + } if (copy_from_user(kern_buf, buf, size)) { ERROR("Stream Write Failed\n"); + palacios_free(kern_buf); return -EFAULT; }; bytes_written = stream->v3_stream->input(stream->v3_stream, kern_buf, size); - kfree(kern_buf); + palacios_free(kern_buf); return bytes_written; } @@ -214,7 +220,11 @@ static void * palacios_stream_open(struct v3_stream * v3_stream, const char * na return NULL; } - stream = kmalloc(sizeof(struct stream_state), GFP_KERNEL); + stream = palacios_alloc(sizeof(struct stream_state)); + if (!stream) { + ERROR("Unable to allocate stream\n"); + return NULL; + } memset(stream, 0, sizeof(struct stream_state)); stream->out_ring = create_ringbuf(STREAM_RING_LEN); @@ -270,7 +280,7 @@ static void palacios_stream_close(struct v3_stream * v3_stream) { free_ringbuf(stream->out_ring); list_del(&(stream->stream_node)); - kfree(stream); + palacios_free(stream); } @@ -351,7 +361,12 @@ static int stream_connect(struct v3_guest * guest, unsigned int cmd, unsigned lo static int guest_stream_init(struct v3_guest * guest, void ** vm_data) { - struct vm_global_streams * state = kmalloc(sizeof(struct vm_global_streams), GFP_KERNEL); + struct vm_global_streams * state = palacios_alloc(sizeof(struct vm_global_streams)); + + if (!state) { + ERROR("Unable to allocate state in stream init\n"); + return -1; + } INIT_LIST_HEAD(&(state->open_streams)); *vm_data = state; @@ -366,6 +381,7 @@ static int guest_stream_deinit(struct v3_guest * guest, void * vm_data) { struct vm_global_streams * state = vm_data; if (!list_empty(&(state->open_streams))) { ERROR("Error shutting down VM with open streams\n"); + return -1; } return 0; diff --git a/linux_module/linux-exts.c b/linux_module/linux-exts.c index e227107..089e67e 100644 --- a/linux_module/linux-exts.c +++ b/linux_module/linux-exts.c @@ -47,7 +47,7 @@ int init_vm_extensions(struct v3_guest * guest) { INFO("Registering Linux Extension (%s)\n", ext_impl->name); - ext = kmalloc(sizeof(struct vm_ext), GFP_KERNEL); + ext = palacios_alloc(sizeof(struct vm_ext)); if (!ext) { WARNING("Error allocating VM extension (%s)\n", ext_impl->name); @@ -80,7 +80,7 @@ int deinit_vm_extensions(struct v3_guest * guest) { } list_del(&(ext->node)); - kfree(ext); + palacios_free(ext); } return 0; diff --git a/linux_module/main.c b/linux_module/main.c index df1c98c..e37f207 100644 --- a/linux_module/main.c +++ b/linux_module/main.c @@ -74,7 +74,7 @@ static long v3_dev_ioctl(struct file * filp, case V3_CREATE_GUEST:{ int vm_minor = 0; struct v3_guest_img user_image; - struct v3_guest * guest = kmalloc(sizeof(struct v3_guest), GFP_KERNEL); + struct v3_guest * guest = palacios_alloc(sizeof(struct v3_guest)); if (IS_ERR(guest)) { ERROR("Palacios: Error allocating Kernel guest_image\n"); @@ -89,6 +89,7 @@ static long v3_dev_ioctl(struct file * filp, if (vm_minor == -1) { ERROR("Palacios Error: Too many VMs are currently running\n"); + palacios_free(guest); return -EFAULT; } @@ -96,6 +97,7 @@ static long v3_dev_ioctl(struct file * filp, if (copy_from_user(&user_image, argp, sizeof(struct v3_guest_img))) { ERROR("Palacios Error: copy from user error getting guest image...\n"); + palacios_free(guest); return -EFAULT; } @@ -106,11 +108,13 @@ static long v3_dev_ioctl(struct file * filp, if (IS_ERR(guest->img)) { ERROR("Palacios Error: Could not allocate space for guest image\n"); + palacios_free(guest); return -EFAULT; } if (copy_from_user(guest->img, user_image.guest_data, guest->img_size)) { ERROR("Palacios: Error loading guest data\n"); + palacios_free(guest); return -EFAULT; } @@ -120,6 +124,8 @@ static long v3_dev_ioctl(struct file * filp, if (create_palacios_vm(guest) == -1) { ERROR("Palacios: Error creating guest\n"); + palacios_free(guest->img); + palacios_free(guest); return -EFAULT; } diff --git a/linux_module/mm.c b/linux_module/mm.c index bb8919a..d71cb96 100644 --- a/linux_module/mm.c +++ b/linux_module/mm.c @@ -11,6 +11,8 @@ #include "palacios.h" +#define OFFLINE_POOL_THRESHOLD 12 + struct mempool { uintptr_t base_addr; u64 num_pages; @@ -66,7 +68,7 @@ static uintptr_t alloc_contig_pgs(u64 num_pages, u32 alignment) { } if (alignment > 0) { - step = alignment / 4096; + step = alignment / PAGE_SIZE; } // Start the search at the correct alignment @@ -74,7 +76,7 @@ static uintptr_t alloc_contig_pgs(u64 num_pages, u32 alignment) { start = ((alignment - (pool.base_addr % alignment)) >> 12); } - ERROR("\t Start idx %d (base_addr=%p)\n", start, (void *)(u64)pool.base_addr); + DEBUG("\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) { @@ -96,11 +98,11 @@ static uintptr_t alloc_contig_pgs(u64 num_pages, u32 alignment) { set_page_bit(j); } - return pool.base_addr + (i * 4096); + return pool.base_addr + (i * PAGE_SIZE); } } - /* ERROR("PALACIOS BAD: LARGE PAGE ALLOCATION FAILED\n"); */ + ERROR("ALERT ALERT Allocation of Large Number of Contiguous Pages FAILED\n"); return 0; } @@ -110,24 +112,45 @@ static uintptr_t alloc_contig_pgs(u64 num_pages, u32 alignment) { uintptr_t alloc_palacios_pgs(u64 num_pages, u32 alignment) { uintptr_t addr = 0; - if ((num_pages < 12)) { + if (num_pages < OFFLINE_POOL_THRESHOLD) { struct page * pgs = NULL; + void *temp; int order = get_order(num_pages * PAGE_SIZE); pgs = alloc_pages(GFP_DMA32, order); - WARN(!pgs, "Could not allocate pages\n"); + if (!pgs) { + ERROR("Could not allocate small number of contigious pages\n"); + return 0; + } - /* if (!pgs) { ERROR("PALACIOS BAD: SMALL PAGE ALLOCATION FAILED\n"); } */ - /* DEBUG("%llu pages (order=%d) aquired from alloc_pages\n", num_pages, order); */ addr = page_to_pfn(pgs) << PAGE_SHIFT; + + temp = (void*)addr; + + if ( (temp>=(void*)(pool.base_addr) && + (temp<((void*)(pool.base_addr)+pool.num_pages*PAGE_SIZE))) + || ((temp+num_pages*PAGE_SIZE)>=(void*)(pool.base_addr) && + ((temp+num_pages*PAGE_SIZE)<((void*)(pool.base_addr)+pool.num_pages*PAGE_SIZE))) ) { + + ERROR("ALERT ALERT Allocation of small number of contiguous pages returned block that " + "OVERLAPS with the offline page pool addr=%p, addr+numpages=%p, " + "pool.base_addr=%p, pool.base_addr+pool.numpages=%p\n", + temp, temp+num_pages*PAGE_SIZE, (void*)(pool.base_addr), + (void*)(pool.base_addr)+pool.num_pages*PAGE_SIZE); + } + + } else { //DEBUG("Allocating %llu pages from bitmap allocator\n", num_pages); //addr = pool.base_addr; addr = alloc_contig_pgs(num_pages, alignment); + if (!addr) { + ERROR("Could not allocate large number of contiguous pages\n"); + } } @@ -141,21 +164,32 @@ void free_palacios_pgs(uintptr_t pg_addr, int num_pages) { //DEBUG("Freeing Memory page %p\n", (void *)pg_addr); if ((pg_addr >= pool.base_addr) && - (pg_addr < pool.base_addr + (4096 * pool.num_pages))) { - int pg_idx = (pg_addr - pool.base_addr) / 4096; + (pg_addr < pool.base_addr + (PAGE_SIZE * pool.num_pages))) { + int pg_idx = (pg_addr - pool.base_addr) / PAGE_SIZE; int i = 0; + + if (num_pages pool.num_pages) { - ERROR("Freeing memory bounds exceeded\n"); + ERROR("Freeing memory bounds exceeded for offline pool\n"); return; } for (i = 0; i < num_pages; i++) { - WARN(get_page_bit(pg_idx + i) == 0, "Trying to free unallocated page\n"); - + if (get_page_bit(pg_idx + i) == 0) { + ERROR("Trying to free unallocated page from offline pool\n"); + } clear_page_bit(pg_idx + i); } + } else { + if (num_pages>=OFFLINE_POOL_THRESHOLD) { + ERROR("ALERT ALERT Large page deallocation from linux pool\n"); + } __free_pages(pfn_to_page(pg_addr >> PAGE_SHIFT), get_order(num_pages * PAGE_SIZE)); } } @@ -175,15 +209,15 @@ int add_palacios_memory(uintptr_t base_addr, u64 num_pages) { } DEBUG("Managing %dMB of memory starting at %llu (%lluMB)\n", - (unsigned int)(num_pages * 4096) / (1024 * 1024), + (unsigned int)(num_pages * PAGE_SIZE) / (1024 * 1024), (unsigned long long)base_addr, (unsigned long long)(base_addr / (1024 * 1024))); - pool.bitmap = kmalloc(bitmap_size, GFP_KERNEL); + pool.bitmap = palacios_alloc(bitmap_size); if (IS_ERR(pool.bitmap)) { - WARNING("Error allocating Palacios MM bitmap\n"); + ERROR("Error allocating Palacios MM bitmap\n"); return -1; } @@ -198,7 +232,7 @@ int add_palacios_memory(uintptr_t base_addr, u64 num_pages) { int palacios_init_mm( void ) { - // INIT_LIST_HEAD(&(pools)); + pool.base_addr = 0; pool.num_pages = 0; pool.bitmap = NULL; @@ -207,7 +241,15 @@ int palacios_init_mm( void ) { } int palacios_deinit_mm( void ) { - kfree(pool.bitmap); + + palacios_free(pool.bitmap); + + pool.bitmap=0; + pool.base_addr=0; + pool.num_pages=0; + + // note that the memory is not onlined here - offlining and onlining + // is the resposibility of the caller return 0; } diff --git a/linux_module/palacios-stubs.c b/linux_module/palacios-stubs.c index eea613b..60b481f 100644 --- a/linux_module/palacios-stubs.c +++ b/linux_module/palacios-stubs.c @@ -48,7 +48,7 @@ static void deinit_print_buffers(void) for (i=0;iname); - kfree(thread_info); + palacios_free(thread_info); // handle cleanup do_exit(ret); @@ -276,7 +289,12 @@ palacios_start_kernel_thread( void * arg, char * thread_name) { - struct lnx_thread_arg * thread_info = kmalloc(sizeof(struct lnx_thread_arg), GFP_KERNEL); + struct lnx_thread_arg * thread_info = palacios_alloc(sizeof(struct lnx_thread_arg)); + + if (!thread_info) { + ERROR("ALERT ALERT Unable to allocate thread\n"); + return NULL; + } thread_info->fn = fn; thread_info->arg = arg; @@ -295,7 +313,12 @@ palacios_start_thread_on_cpu(int cpu_id, void * arg, char * thread_name ) { struct task_struct * thread = NULL; - struct lnx_thread_arg * thread_info = kmalloc(sizeof(struct lnx_thread_arg), GFP_KERNEL); + struct lnx_thread_arg * thread_info = palacios_alloc(sizeof(struct lnx_thread_arg)); + + if (!thread_info) { + ERROR("ALERT ALERT Unable to allocate thread to start on cpu\n"); + return NULL; + } thread_info->fn = fn; thread_info->arg = arg; @@ -306,11 +329,14 @@ palacios_start_thread_on_cpu(int cpu_id, if (IS_ERR(thread)) { WARNING("Palacios error creating thread: %s\n", thread_name); + palacios_free(thread_info); return NULL; } if (set_cpus_allowed_ptr(thread, cpumask_of(cpu_id)) != 0) { + WARNING("Attempt to start thread on disallowed CPU\n"); kthread_stop(thread); + palacios_free(thread_info); return NULL; } @@ -438,7 +464,8 @@ palacios_hook_interrupt(struct v3_vm_info * vm, //set_idtvec_handler(vector, palacios_dispatch_interrupt); if (vector < 32) { - panic("unexpected vector for hooking\n"); + ERROR("unexpected vector for hooking\n"); + return -1; } else { int device_id = 0; @@ -461,7 +488,8 @@ palacios_hook_interrupt(struct v3_vm_info * vm, if (error) { ERROR("error code for request_irq is %d\n", error); - panic("request vector %d failed", vector); + ERROR("request vector %d failed", vector); + return -1; } } @@ -538,10 +566,13 @@ void palacios_yield_cpu_timed(unsigned int us) void * palacios_mutex_alloc(void) { - spinlock_t *lock = kmalloc(sizeof(spinlock_t), GFP_KERNEL); + spinlock_t *lock = palacios_alloc(sizeof(spinlock_t)); if (lock) { spin_lock_init(lock); + } else { + ERROR("ALERT ALERT Unable to allocate lock\n"); + return NULL; } return lock; @@ -552,7 +583,7 @@ palacios_mutex_alloc(void) */ void palacios_mutex_free(void * mutex) { - kfree(mutex); + palacios_free(mutex); } /** @@ -591,7 +622,7 @@ palacios_mutex_unlock( /** - * Unlocks a mutex. + * Unlocks a mutex and restores previous interrupt state on this core */ void palacios_mutex_unlock_irqrestore(void *mutex, void *flags) @@ -643,7 +674,7 @@ int palacios_vmm_init( void ) int minor = 0; int i = 0; - cpu_mask = kmalloc((num_cpus / 8) + 1, GFP_KERNEL); + cpu_mask = palacios_alloc((num_cpus / 8) + 1); if (!cpu_mask) { ERROR("Cannot allocate cpu mask\n"); @@ -669,7 +700,7 @@ int palacios_vmm_init( void ) if (init_print_buffers()) { ERROR("Cannot initialize print buffers\n"); - kfree(cpu_mask); + palacios_free(cpu_mask); return -1; } diff --git a/linux_module/palacios-vnet-brg.c b/linux_module/palacios-vnet-brg.c index 7f4ab13..efb7d18 100644 --- a/linux_module/palacios-vnet-brg.c +++ b/linux_module/palacios-vnet-brg.c @@ -109,7 +109,7 @@ static void _delete_link(struct vnet_link * link){ link->dst_port, link->idx); - kfree(link); + palacios_free(link); link = NULL; } @@ -185,7 +185,7 @@ uint32_t vnet_brg_add_link(uint32_t ip, uint16_t port, vnet_brg_proto_t proto){ struct vnet_link * new_link = NULL; uint32_t idx; - new_link = kmalloc(sizeof(struct vnet_link), GFP_KERNEL); + new_link = palacios_alloc(sizeof(struct vnet_link)); if (!new_link) { return -1; } @@ -198,7 +198,7 @@ uint32_t vnet_brg_add_link(uint32_t ip, uint16_t port, vnet_brg_proto_t proto){ idx = _create_link(new_link); if (idx < 0) { WARNING("Could not create link\n"); - kfree(new_link); + palacios_free(new_link); return -1; } @@ -413,7 +413,12 @@ static int _udp_server(void * arg) { INFO("Palacios VNET Bridge: UDP receiving server ..... \n"); - pkt = kmalloc(MAX_PACKET_LEN, GFP_KERNEL); + pkt = palacios_alloc(MAX_PACKET_LEN); + + if (!pkt) { + ERROR("Unable to allocate packet in VNET UDP Server\n"); + return -1; + } while (!kthread_should_stop()) { @@ -455,7 +460,7 @@ static int _udp_server(void * arg) { INFO("VNET Server: UDP thread exiting\n"); - kfree(pkt); + palacios_free(pkt); return 0; } diff --git a/linux_module/palacios-vnet-ctrl.c b/linux_module/palacios-vnet-ctrl.c index 9495cb4..f8043b7 100644 --- a/linux_module/palacios-vnet-ctrl.c +++ b/linux_module/palacios-vnet-ctrl.c @@ -544,7 +544,7 @@ static void delete_route(struct vnet_route_iter * route) { INFO("VNET Control: Route %d deleted from VNET\n", route->idx); - kfree(route); + palacios_free(route); route = NULL; } @@ -593,21 +593,24 @@ route_write(struct file * file, if (strnicmp("ADD", token, strlen("ADD")) == 0) { struct vnet_route_iter * new_route = NULL; - new_route = kmalloc(sizeof(struct vnet_route_iter), GFP_KERNEL); + new_route = palacios_alloc(sizeof(struct vnet_route_iter)); if (!new_route) { + ERROR("Cannot allocate new route\n"); return -ENOMEM; } memset(new_route, 0, sizeof(struct vnet_route_iter)); if (parse_route_str(buf_iter, &(new_route->route)) == -1) { - kfree(new_route); + ERROR("Cannot parse new route\n"); + palacios_free(new_route); return -EFAULT; } if (inject_route(new_route) != 0) { - kfree(new_route); + ERROR("Cannot inject new route\n"); + palacios_free(new_route); return -EFAULT; } } else if (strnicmp("DEL", token, strlen("DEL")) == 0) { @@ -651,7 +654,7 @@ static void delete_link(struct vnet_link_iter * link){ vnet_ctrl_s.num_links --; spin_unlock_irqrestore(&(vnet_ctrl_s.lock), flags); - kfree(link); + palacios_free(link); link = NULL; } @@ -728,7 +731,12 @@ link_write(struct file * file, const char * buf, size_t size, loff_t * ppos) { return -EFAULT; } - link = kmalloc(sizeof(struct vnet_link_iter), GFP_KERNEL); + link = palacios_alloc(sizeof(struct vnet_link_iter)); + if (!link) { + WARNING("VNET Control: Cannot allocate link\n"); + return -EFAULT; + } + memset(link, 0, sizeof(struct vnet_link_iter)); link->dst_ip = d_ip; diff --git a/linux_module/palacios-vnet.c b/linux_module/palacios-vnet.c index 297852d..25537aa 100644 --- a/linux_module/palacios-vnet.c +++ b/linux_module/palacios-vnet.c @@ -86,7 +86,12 @@ static void * host_create_timer(unsigned long interval, void (* timer_fun)(void * priv_data), void * data){ - struct host_timer * timer = (struct host_timer *)kmalloc(sizeof(struct host_timer), GFP_KERNEL); + struct host_timer * timer = (struct host_timer *)palacios_alloc(sizeof(struct host_timer)); + + if (!timer) { + ERROR("Unable to allocate timer in VNET\n"); + return NULL; + } timer->interval = interval; timer->timer_fun = timer_fun; @@ -130,7 +135,7 @@ host_del_timer(void * vnet_timer){ del_timer(&(timer->timer)); - kfree(timer); + palacios_free(timer); } diff --git a/linux_module/util-hashtable.c b/linux_module/util-hashtable.c index 669bbfb..beb7bbe 100644 --- a/linux_module/util-hashtable.c +++ b/linux_module/util-hashtable.c @@ -38,7 +38,8 @@ #include #include #include - + +#include "palacios.h" #include "util-hashtable.h" @@ -138,18 +139,18 @@ static inline uint_t indexFor(uint_t table_length, uint_t hash_value) { return (hash_value % table_length); }; -#define freekey(X) kfree(X) +#define freekey(X) palacios_free(X) static void * tmp_realloc(void * old_ptr, uint_t old_size, uint_t new_size) { - void * new_buf = kmalloc(new_size, GFP_KERNEL); + void * new_buf = palacios_alloc(new_size); if (new_buf == NULL) { return NULL; } memcpy(new_buf, old_ptr, old_size); - kfree(old_ptr); + palacios_free(old_ptr); return new_buf; } @@ -202,16 +203,16 @@ struct hashtable * palacios_create_htable(uint_t min_size, } } - htable = (struct hashtable *)kmalloc(sizeof(struct hashtable), GFP_KERNEL); + htable = (struct hashtable *)palacios_alloc(sizeof(struct hashtable)); if (htable == NULL) { return NULL; /*oom*/ } - htable->table = (struct hash_entry **)kmalloc(sizeof(struct hash_entry*) * size, GFP_KERNEL); + htable->table = (struct hash_entry **)palacios_alloc(sizeof(struct hash_entry*) * size); if (htable->table == NULL) { - kfree(htable); + palacios_free(htable); return NULL; /*oom*/ } @@ -244,7 +245,7 @@ static int hashtable_expand(struct hashtable * htable) { new_size = primes[++(htable->prime_index)]; - new_table = (struct hash_entry **)kmalloc(sizeof(struct hash_entry*) * new_size, GFP_KERNEL); + new_table = (struct hash_entry **)palacios_alloc(sizeof(struct hash_entry*) * new_size); if (new_table != NULL) { memset(new_table, 0, new_size * sizeof(struct hash_entry *)); @@ -264,7 +265,7 @@ static int hashtable_expand(struct hashtable * htable) { } } - kfree(htable->table); + palacios_free(htable->table); htable->table = new_table; } else { @@ -326,7 +327,7 @@ int palacios_htable_insert(struct hashtable * htable, addr_t key, addr_t value) hashtable_expand(htable); } - new_entry = (struct hash_entry *)kmalloc(sizeof(struct hash_entry), GFP_KERNEL); + new_entry = (struct hash_entry *)palacios_alloc(sizeof(struct hash_entry)); if (new_entry == NULL) { (htable->entry_count)--; @@ -364,7 +365,7 @@ int palacios_htable_change(struct hashtable * htable, addr_t key, addr_t value, if ((hash_value == tmp_entry->hash) && (htable->eq_fn(key, tmp_entry->key))) { if (free_value) { - kfree((void *)(tmp_entry->value)); + palacios_free((void *)(tmp_entry->value)); } tmp_entry->value = value; @@ -481,7 +482,7 @@ addr_t palacios_htable_remove(struct hashtable * htable, addr_t key, int free_ke if (free_key) { freekey((void *)(cursor->key)); } - kfree(cursor); + palacios_free(cursor); return value; } @@ -511,8 +512,8 @@ void palacios_free_htable(struct hashtable * htable, int free_values, int free_k if (free_keys) { freekey((void *)(tmp->key)); } - kfree((void *)(tmp->value)); - kfree(tmp); + palacios_free((void *)(tmp->value)); + palacios_free(tmp); } } } else { @@ -528,12 +529,12 @@ void palacios_free_htable(struct hashtable * htable, int free_values, int free_k if (free_keys) { freekey((void *)(tmp->key)); } - kfree(tmp); + palacios_free(tmp); } } } - kfree(htable->table); - kfree(htable); + palacios_free(htable->table); + palacios_free(htable); } diff --git a/linux_module/util-queue.c b/linux_module/util-queue.c index 0c51f8d..f7f6146 100644 --- a/linux_module/util-queue.c +++ b/linux_module/util-queue.c @@ -5,6 +5,7 @@ #include +#include "palacios.h" #include "util-queue.h" void init_queue(struct gen_queue * queue, unsigned int max_entries) { @@ -16,7 +17,11 @@ void init_queue(struct gen_queue * queue, unsigned int max_entries) { } struct gen_queue * create_queue(unsigned int max_entries) { - struct gen_queue * tmp_queue = kmalloc(sizeof(struct gen_queue), GFP_KERNEL); + struct gen_queue * tmp_queue = palacios_alloc(sizeof(struct gen_queue)); + if (!tmp_queue) { + ERROR("Unable to allocate a queue\n"); + return NULL; + } init_queue(tmp_queue, max_entries); return tmp_queue; } @@ -29,7 +34,12 @@ int enqueue(struct gen_queue * queue, void * entry) { return -1; } - q_entry = kmalloc(sizeof(struct queue_entry), GFP_KERNEL); + q_entry = palacios_alloc(sizeof(struct queue_entry)); + + if (!q_entry) { + ERROR("Unable to allocate a queue entry on enqueue\n"); + return -1; + } spin_lock_irqsave(&(queue->lock), flags); @@ -55,7 +65,7 @@ void * dequeue(struct gen_queue * queue) { entry_val = tmp_entry->entry; list_del(q_entry); - kfree(tmp_entry); + palacios_free(tmp_entry); queue->num_entries--; diff --git a/linux_module/util-ringbuffer.c b/linux_module/util-ringbuffer.c index d52d25d..9d0935d 100644 --- a/linux_module/util-ringbuffer.c +++ b/linux_module/util-ringbuffer.c @@ -12,7 +12,13 @@ #include "util-ringbuffer.h" void init_ringbuf(struct ringbuf * ring, unsigned int size) { - ring->buf = kmalloc(size, GFP_KERNEL); + ring->buf = palacios_alloc(size); + + if (!(ring->buf)) { + ERROR("Cannot allocate ring buffer data\n"); + size=0; + } + ring->size = size; ring->start = 0; @@ -21,15 +27,21 @@ void init_ringbuf(struct ringbuf * ring, unsigned int size) { } struct ringbuf * create_ringbuf(unsigned int size) { - struct ringbuf * ring = (struct ringbuf *)kmalloc(sizeof(struct ringbuf), GFP_KERNEL); + struct ringbuf * ring = (struct ringbuf *)palacios_alloc(sizeof(struct ringbuf)); + + if (!ring) { + ERROR("Cannot allocate ring buffer\n"); + return NULL; + } + init_ringbuf(ring, size); return ring; } void free_ringbuf(struct ringbuf * ring) { - kfree(ring->buf); - kfree(ring); + palacios_free(ring->buf); + palacios_free(ring); } static inline unsigned char * get_read_ptr(struct ringbuf * ring) { diff --git a/linux_module/vm.c b/linux_module/vm.c index 06a016a..842d472 100644 --- a/linux_module/vm.c +++ b/linux_module/vm.c @@ -70,7 +70,7 @@ int add_guest_ctrl(struct v3_guest * guest, unsigned int cmd, unsigned int cmd, unsigned long arg, void * priv_data), void * priv_data) { - struct vm_ctrl * ctrl = kmalloc(sizeof(struct vm_ctrl), GFP_KERNEL); + struct vm_ctrl * ctrl = palacios_alloc(sizeof(struct vm_ctrl)); if (ctrl == NULL) { WARNING("Error: Could not allocate vm ctrl %d\n", cmd); @@ -83,7 +83,7 @@ int add_guest_ctrl(struct v3_guest * guest, unsigned int cmd, if (__insert_ctrl(guest, ctrl) != NULL) { WARNING("Could not insert guest ctrl %d\n", cmd); - kfree(ctrl); + palacios_free(ctrl); return -1; } @@ -355,7 +355,7 @@ int free_palacios_vm(struct v3_guest * guest) { cdev_del(&(guest->cdev)); vfree(guest->img); - kfree(guest); + palacios_free(guest); return 0; }