static int64_t ioctl_unload_vmm(void) { int64_t i; int64_t ret; int64_t status = BF_IOCTL_SUCCESS; ret = common_unload_vmm(); if (ret != BF_SUCCESS) { ALERT("IOCTL_UNLOAD_VMM: common_unload_vmm failed: %p - %s\n", (void *)ret, ec_to_str(ret)); status = BF_IOCTL_FAILURE; } for (i = 0; i < g_num_pmodules; i++) platform_free_rwe(pmodules[i].data, pmodules[i].size); g_num_pmodules = 0; platform_memset(&pmodules, 0, sizeof(pmodules)); if (status == BF_IOCTL_SUCCESS) DEBUG("IOCTL_UNLOAD_VMM: succeeded\n"); return status; }
static long ioctl_unload_vmm(void) { int i; int64_t ret; long status = BF_IOCTL_SUCCESS; ret = common_unload_vmm(); if (ret != BF_SUCCESS) { ALERT("IOCTL_UNLOAD_VMM: common_unload_vmm failed: %p - %s\n", \ (void *)ret, ec_to_str(ret)); status = BF_IOCTL_FAILURE; } for (i = 0; i < g_num_files; i++) { vfree(files[i]); files[i] = 0; files_size[i] = 0; } g_num_files = 0; if (status == BF_IOCTL_SUCCESS) DEBUG("IOCTL_UNLOAD_VMM: succeeded\n"); return status; }
static int64_t ioctl_vmcall(struct vmcall_registers_t *inregs, struct vmcall_registers_t *outregs) { int64_t ret; ret = common_vmcall(inregs, g_cpuid); if (ret != 0) { ALERT("IOCTL_VMCALL: common_vmcall failed: %p - %s\n", \ (void *)ret, ec_to_str(ret)); return BF_IOCTL_FAILURE; } RtlCopyMemory(outregs, inregs, sizeof(struct vmcall_registers_t)); return BF_IOCTL_SUCCESS; }
static int64_t ioctl_add_module(char *file, int64_t len) { char *buf; int64_t ret; if (g_num_pmodules >= MAX_NUM_MODULES) { ALERT("IOCTL_ADD_MODULE: too many modules have been loaded\n"); return BF_IOCTL_FAILURE; } buf = platform_alloc_rwe(len); if (buf == NULL) { ALERT("IOCTL_ADD_MODULE: failed to allocate memory for the module\n"); return BF_IOCTL_FAILURE; } platform_memset(buf, 0, len); platform_memcpy(buf, file, len); ret = common_add_module(buf, len); if (ret != BF_SUCCESS) { ALERT("IOCTL_ADD_MODULE: common_add_module failed: %p - %s\n", (void *)ret, ec_to_str(ret)); goto failed; } pmodules[g_num_pmodules].data = buf; pmodules[g_num_pmodules].size = len; g_num_pmodules++; DEBUG("IOCTL_ADD_MODULE: succeeded\n"); return BF_IOCTL_SUCCESS; failed: platform_free_rwe(buf, len); DEBUG("IOCTL_ADD_MODULE: failed\n"); return BF_IOCTL_FAILURE; }
static int64_t ioctl_dump_vmm(struct debug_ring_resources_t *user_drr) { int64_t ret; struct debug_ring_resources_t *drr = 0; ret = common_dump_vmm(&drr, g_vcpuid); if (ret != BF_SUCCESS) { ALERT("IOCTL_DUMP_VMM: common_dump_vmm failed: %p - %s\n", (void *)ret, ec_to_str(ret)); return BF_IOCTL_FAILURE; } platform_memcpy(user_drr, drr, sizeof(struct debug_ring_resources_t)); DEBUG("IOCTL_DUMP_VMM: succeeded\n"); return BF_IOCTL_SUCCESS; }
static int64_t ioctl_stop_vmm(void) { int64_t ret; int64_t status = BF_IOCTL_SUCCESS; ret = common_stop_vmm(); if (ret != BF_SUCCESS) { ALERT("IOCTL_STOP_VMM: ioctl_stop_vmm failed: %p - %s\n", (void *)ret, ec_to_str(ret)); status = BF_IOCTL_FAILURE; } if (status == BF_IOCTL_SUCCESS) DEBUG("IOCTL_STOP_VMM: succeeded\n"); return status; }
static int64_t ioctl_start_vmm(void) { int64_t ret; ret = common_start_vmm(); if (ret != BF_SUCCESS) { ALERT("IOCTL_START_VMM: ioctl_start_vmm failed: %p - %s\n", (void *)ret, ec_to_str(ret)); goto failure; } DEBUG("IOCTL_START_VMM: succeeded\n"); return BF_IOCTL_SUCCESS; failure: ioctl_stop_vmm(); return BF_IOCTL_FAILURE; }
static long ioctl_load_vmm(void) { int64_t ret; ret = common_load_vmm(); if (ret != BF_SUCCESS) { ALERT("IOCTL_LOAD_VMM: common_load_vmm failed: %p - %s\n", \ (void *)ret, ec_to_str(ret)); goto failure; } DEBUG("IOCTL_LOAD_VMM: succeeded\n"); return BF_IOCTL_SUCCESS; failure: ioctl_unload_vmm(); return BF_IOCTL_FAILURE; }
static long ioctl_dump_vmm(struct debug_ring_resources_t *user_drr) { int64_t ret; struct debug_ring_resources_t *drr = 0; ret = common_dump_vmm(&drr, g_vcpuid); if (ret != BF_SUCCESS) { ALERT("IOCTL_DUMP_VMM: common_dump_vmm failed: %p - %s\n", \ (void *)ret, ec_to_str(ret)); return BF_IOCTL_FAILURE; } ret = copy_to_user(user_drr, drr, sizeof(struct debug_ring_resources_t)); if (ret != 0) { ALERT("IOCTL_DUMP_VMM: failed to copy memory from userspace\n"); return BF_IOCTL_FAILURE; } DEBUG("IOCTL_DUMP_VMM: succeeded\n"); return BF_IOCTL_SUCCESS; }
const char * bfelf_error(bfelf64_sword value) { return ec_to_str(value); }
static long ioctl_add_module(char *file) { char *buf; int64_t ret; if (g_num_files >= MAX_NUM_MODULES) { ALERT("IOCTL_ADD_MODULE: too many modules have been loaded\n"); return BF_IOCTL_FAILURE; } /* * On Linux, we are not given a size for the IOCTL. Appearently * it is common practice to seperate this information into two * different IOCTLs, which is what we do here. This however means * that we have to store state, so userspace has to be careful * to send these IOCTLs in the correct order. * * Linux also does not copy userspace memory for us, so we need * to do this ourselves. As a result, we alloc memory for the * buffer that userspace is providing us so that we can copy this * memory from userspace as needed. */ buf = vmalloc(g_module_length); if (buf == NULL) { ALERT("IOCTL_ADD_MODULE: failed to allocate memory for the module\n"); return BF_IOCTL_FAILURE; } ret = copy_from_user(buf, file, g_module_length); if (ret != 0) { ALERT("IOCTL_ADD_MODULE: failed to copy memory from userspace\n"); goto failed; } ret = common_add_module(buf, g_module_length); if (ret != BF_SUCCESS) { ALERT("IOCTL_ADD_MODULE: common_add_module failed: %p - %s\n", \ (void *)ret, ec_to_str(ret)); goto failed; } files[g_num_files] = buf; files_size[g_num_files] = g_module_length; g_num_files++; DEBUG("IOCTL_ADD_MODULE: succeeded\n"); return BF_IOCTL_SUCCESS; failed: vfree(buf); DEBUG("IOCTL_ADD_MODULE: failed\n"); return BF_IOCTL_FAILURE; }