#include "palacios.h"
#include "mm.h"
#include "vm.h"
+#include "allow_devmem.h"
+#include "lockcheck.h"
#include "linux-exts.h"
-
MODULE_LICENSE("GPL");
// Module parameter
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");
+static int allow_devmem = 0;
+module_param(allow_devmem, int, 0);
+MODULE_PARM_DESC(allow_devmem, "Allow general user-space /dev/mem access even if kernel is strict");
+
+// 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};
guest->img_size = user_image.size;
DEBUG("Palacios: Allocating kernel memory for guest image (%llu bytes)\n", user_image.size);
- guest->img = vmalloc(guest->img_size);
+ guest->img = palacios_valloc(guest->img_size);
if (IS_ERR(guest->img)) {
ERROR("Palacios Error: Could not allocate space for guest image\n");
out_err2:
- vfree(guest->img);
+ palacios_vfree(guest->img);
out_err1:
guest_map[vm_minor] = NULL;
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);
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 (len<count) {
- len += snprintf(buf+len, count-len,
- "%s\t/dev/v3-vm%d\n",
- guest_map[i]->name, 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;j<s->num_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;
}
}
+
+
+
static int __init v3_init(void) {
+
dev_t dev = MKDEV(0, 0); // We dynamicallly assign the major number
int ret = 0;
+ LOCKCHECK_INIT();
palacios_init_mm();
+ if (allow_devmem) {
+ palacios_allow_devmem();
+ }
+
// Initialize Palacios
- palacios_vmm_init();
+ palacios_vmm_init(options);
// initialize extensions
extern u32 pg_frees;
extern u32 mallocs;
extern u32 frees;
+ extern u32 vmallocs;
+ extern u32 vfrees;
int i = 0;
struct v3_guest * guest;
dev_t dev;
palacios_vmm_exit();
DEBUG("Palacios Mallocs = %d, Frees = %d\n", mallocs, frees);
+ DEBUG("Palacios Vmallocs = %d, Vfrees = %d\n", vmallocs, vfrees);
DEBUG("Palacios Page Allocs = %d, Page Frees = %d\n", pg_allocs, pg_frees);
unregister_chrdev_region(MKDEV(v3_major_num, 0), MAX_VMS + 1);
deinit_lnx_extensions();
+ if (allow_devmem) {
+ palacios_restore_devmem();
+ }
+
palacios_deinit_mm();
remove_proc_entry("v3-guests", dir);
remove_proc_entry("v3vee", NULL);
DEBUG("Palacios Module Mallocs = %d, Frees = %d\n", mod_allocs, mod_frees);
+
+ LOCKCHECK_DEINIT();
}
void * addr = NULL;
mod_allocs++;
- addr = kmalloc(size, flags);
+ addr = palacios_alloc_extended(size, flags);
return addr;
}
void trace_free(const void * objp) {
mod_frees++;
- kfree(objp);
+ palacios_free((void*)objp);
}