X-Git-Url: http://v3vee.org/palacios/gitweb/gitweb.cgi?a=blobdiff_plain;f=linux_module%2Fmain.c;h=296d01bbc6171a60c1196cd18f537d00109b1957;hb=c1810f8134ef829599525d30856970f0155da1f3;hp=57917e0857e29eee02eb8a9c47fbf51d5a0e2cff;hpb=47dc84c2e6854edb598062918070b2da97e8f10a;p=palacios.git diff --git a/linux_module/main.c b/linux_module/main.c index 57917e0..296d01b 100644 --- a/linux_module/main.c +++ b/linux_module/main.c @@ -21,6 +21,8 @@ #include +#include + #include "palacios.h" #include "mm.h" #include "vm.h" @@ -37,10 +39,14 @@ int cpu_list_len = 0; module_param_array(cpu_list, int, &cpu_list_len, 0644); MODULE_PARM_DESC(cpu_list, "Comma-delimited list of CPUs that Palacios will run on"); +// Palacios options parameter +static char *options; +module_param(options, charp, 0); +MODULE_PARM_DESC(options, "Generic options to internal Palacios modules"); + int mod_allocs = 0; int mod_frees = 0; - static int v3_major_num = 0; static struct v3_guest * guest_map[MAX_VMS] = {[0 ... MAX_VMS - 1] = 0}; @@ -139,7 +145,14 @@ out_err: } case V3_FREE_GUEST: { unsigned long vm_idx = arg; - struct v3_guest * guest = guest_map[vm_idx]; + struct v3_guest * guest; + + if (vm_idx > MAX_VMS) { + ERROR("Invalid VM index: %ld\n", vm_idx); + return -1; + } + + guest = guest_map[vm_idx]; if (!guest) { ERROR("No VM at index %ld\n",vm_idx); @@ -148,7 +161,11 @@ out_err: INFO("Freeing VM (%s) (%p)\n", guest->name, guest); - free_palacios_vm(guest); + if (free_palacios_vm(guest)<0) { + ERROR("Cannot free guest at index %ld\n",vm_idx); + return -1; + } + guest_map[vm_idx] = NULL; break; } @@ -172,9 +189,25 @@ out_err: break; } - default: - ERROR("\tUnhandled\n"); + case V3_RESET_MEMORY: { + if (palacios_init_mm() == -1) { + ERROR("Error resetting Palacios memory\n"); + return -EFAULT; + } + break; + } + + default: { + struct global_ctrl * ctrl = get_global_ctrl(ioctl); + + if (ctrl) { + return ctrl->handler(ioctl, arg); + } + + WARNING("\tUnhandled global ctrl cmd: %d\n", ioctl); + return -EINVAL; + } } return 0; @@ -195,22 +228,95 @@ struct proc_dir_entry *palacios_get_procdir(void) return dir; } + +#define MAX_VCORES 32 + static int read_guests(char * buf, char ** start, off_t off, int count, int * eof, void * data) { int len = 0; unsigned int i = 0; + + struct v3_vm_state *s =palacios_alloc(sizeof(struct v3_vm_state)+MAX_VCORES*sizeof(struct v3_vcore_state)); + + if (!s) { + ERROR("No space for state structure\n"); + goto out; + } for(i = 0; i < MAX_VMS; i++) { - if (guest_map[i] != NULL) { - if (lenname, i); + if (guest_map[i] != NULL) { + if (len>=count) { + goto out; + } else { + len += snprintf(buf+len, count-len, + "%s\t/dev/v3-vm%d ", + guest_map[i]->name, i); + + if (len>=count) { + *(buf+len-1)='\n'; + goto out; + } else { + // Get extended data + s->num_vcores=MAX_VCORES; // max we can handle + if (v3_get_state_vm(guest_map[i]->v3_ctx, s)) { + ERROR("Cannot get VM info\n"); + *(buf+len-1)='\n'; + goto out; + } else { + unsigned long j; + + len+=snprintf(buf+len, count-len, + "%s [0x%p-0x%p] %lu vcores ", + s->state==V3_VM_INVALID ? "INVALID" : + s->state==V3_VM_RUNNING ? "running" : + s->state==V3_VM_STOPPED ? "stopped" : + s->state==V3_VM_PAUSED ? "paused" : + s->state==V3_VM_ERROR ? "ERROR" : + s->state==V3_VM_SIMULATING ? "simulating" : "UNKNOWN", + s->mem_base_paddr, s->mem_base_paddr+s->mem_size-1, + s->num_vcores); + if (len>=count) { + *(buf+len-1)='\n'; + goto out; + } + for (j=0;jnum_vcores;j++) { + len+=snprintf(buf+len, count-len, + "[vcore %lu %s on pcore %lu %llu exits rip=0x%p %s %s %s] ", + j, + s->vcore[j].state==V3_VCORE_INVALID ? "INVALID" : + s->vcore[j].state==V3_VCORE_RUNNING ? "running" : + s->vcore[j].state==V3_VCORE_STOPPED ? "stopped" : "UNKNOWN", + s->vcore[j].pcore, + s->vcore[j].num_exits, + s->vcore[j].last_rip, + s->vcore[j].cpu_mode==V3_VCORE_CPU_REAL ? "real" : + s->vcore[j].cpu_mode==V3_VCORE_CPU_PROTECTED ? "protected" : + s->vcore[j].cpu_mode==V3_VCORE_CPU_PROTECTED_PAE ? "protectedpae" : + s->vcore[j].cpu_mode==V3_VCORE_CPU_LONG ? "long" : + s->vcore[j].cpu_mode==V3_VCORE_CPU_LONG_32_COMPAT ? "long32" : + s->vcore[j].cpu_mode==V3_VCORE_CPU_LONG_16_COMPAT ? "long16" : "UNKNOWN", + s->vcore[j].mem_mode==V3_VCORE_MEM_MODE_PHYSICAL ? "physical" : + s->vcore[j].mem_mode==V3_VCORE_MEM_MODE_VIRTUAL ? "virtual" : "UNKNOWN", + s->vcore[j].mem_state==V3_VCORE_MEM_STATE_SHADOW ? "shadow" : + s->vcore[j].mem_state==V3_VCORE_MEM_STATE_NESTED ? "nested" : "UNKNOWN"); + if (len>=count) { + *(buf+len-1)='\n'; + goto out; + } + } + + *(buf+len-1)='\n'; + } + } } + } } - + + out: + if (s) { palacios_free(s); } + return len; } @@ -234,7 +340,7 @@ static int __init v3_init(void) { palacios_init_mm(); // Initialize Palacios - palacios_vmm_init(); + palacios_vmm_init(options); // initialize extensions @@ -316,13 +422,25 @@ static void __exit v3_exit(void) { extern u32 pg_frees; extern u32 mallocs; extern u32 frees; + int i = 0; + struct v3_guest * guest; + dev_t dev; - // should probably try to stop any guests + /* Stop and free any running VMs */ + for (i = 0; i < MAX_VMS; i++) { + if (guest_map[i] != NULL) { + guest = (struct v3_guest *)guest_map[i]; + if (v3_stop_vm(guest->v3_ctx) < 0) + ERROR("Couldn't stop VM %d\n", i); + free_palacios_vm(guest); + guest_map[i] = NULL; + } + } - dev_t dev = MKDEV(v3_major_num, MAX_VMS + 1); + dev = MKDEV(v3_major_num, MAX_VMS + 1); INFO("Removing V3 Control device\n");