From: Oscar Mondragon Date: Mon, 18 Aug 2014 21:37:57 +0000 (-0600) Subject: Hook for thread creation split into create and start thread X-Git-Url: http://v3vee.org/palacios/gitweb/gitweb.cgi?p=palacios.git;a=commitdiff_plain;h=ed88df2e8e304ac4b391521d47c192127ad9bc5a Hook for thread creation split into create and start thread --- diff --git a/linux_module/palacios-stubs.c b/linux_module/palacios-stubs.c index 965d578..90b3ad4 100644 --- a/linux_module/palacios-stubs.c +++ b/linux_module/palacios-stubs.c @@ -442,7 +442,7 @@ palacios_start_kernel_thread( * Starts a kernel thread on the specified CPU. */ void * -palacios_start_thread_on_cpu(int cpu_id, +palacios_create_thread_on_cpu(int cpu_id, int (*fn)(void * arg), void * arg, char * thread_name ) { @@ -474,12 +474,16 @@ palacios_start_thread_on_cpu(int cpu_id, return NULL; } - wake_up_process(thread); - return thread; } +void +palacios_start_thread(void * th){ + struct task_struct * thread = (struct task_struct *)th; + wake_up_process(thread); + +} /** * Rebind a kernel thread to the specified CPU * The thread will be running on target CPU on return @@ -858,7 +862,8 @@ static struct v3_os_hooks palacios_os_hooks = { .get_cpu = palacios_get_cpu, .interrupt_cpu = palacios_interrupt_cpu, .call_on_cpu = palacios_xcall, - .start_thread_on_cpu = palacios_start_thread_on_cpu, + .create_thread_on_cpu = palacios_start_thread_on_cpu, + .start_thread = palacios_start_thread, .move_thread_to_cpu = palacios_move_thread_to_cpu, }; diff --git a/palacios/include/palacios/vmm.h b/palacios/include/palacios/vmm.h index 7aba5de..db94298 100644 --- a/palacios/include/palacios/vmm.h +++ b/palacios/include/palacios/vmm.h @@ -217,12 +217,19 @@ int v3_get_vcore(struct guest_info *); #define V3_CREATE_THREAD_ON_CPU(cpu, fn, arg, name) ({ \ void * thread = NULL; \ extern struct v3_os_hooks * os_hooks; \ - if ((os_hooks) && (os_hooks)->start_thread_on_cpu) { \ - thread = (os_hooks)->start_thread_on_cpu(cpu, fn, arg, name); \ + if ((os_hooks) && (os_hooks)->create_thread_on_cpu) { \ + thread = (os_hooks)->create_thread_on_cpu(cpu, fn, arg, name); \ } \ thread; \ }) +#define V3_START_THREAD(thread) ({ \ + extern struct v3_os_hooks * os_hooks; \ + if((os_hooks) && (os_hooks)->start_thread){ \ + (os_hooks)->start_thread(thread); \ + } \ + }) + #define V3_MOVE_THREAD_TO_CPU(pcpu, thread) ({ \ int ret = -1; \ extern struct v3_os_hooks * os_hooks; \ @@ -354,7 +361,8 @@ struct v3_os_hooks { void * (*start_kernel_thread)(int (*fn)(void * arg), void * arg, char * thread_name); void (*interrupt_cpu)(struct v3_vm_info * vm, int logical_cpu, int vector); void (*call_on_cpu)(int logical_cpu, void (*fn)(void * arg), void * arg); - void * (*start_thread_on_cpu)(int cpu_id, int (*fn)(void * arg), void * arg, char * thread_name); + void * (*create_thread_on_cpu)(int cpu_id, int (*fn)(void * arg), void * arg, char * thread_name); + void (*start_thread)(void * core_thread); int (*move_thread_to_cpu)(int cpu_id, void * thread); }; diff --git a/palacios/src/palacios/vmm.c b/palacios/src/palacios/vmm.c index 490f106..b5740a6 100644 --- a/palacios/src/palacios/vmm.c +++ b/palacios/src/palacios/vmm.c @@ -265,9 +265,42 @@ v3_cpu_arch_t v3_get_cpu_type(int cpu_id) { return v3_cpu_types[cpu_id]; } +static int start_core(void * p) +{ + struct guest_info * core = (struct guest_info *)p; + + if (v3_scheduler_register_core(core) == -1){ + PrintError(core->vm_info, core,"Error initializing scheduling in core %d\n", core->vcpu_id); + } + + PrintDebug(core->vm_info,core,"virtual core %u (on logical core %u): in start_core (RIP=%p)\n", + core->vcpu_id, core->pcpu_id, (void *)(addr_t)core->rip); + + switch (v3_mach_type) { +#ifdef V3_CONFIG_SVM + case V3_SVM_CPU: + case V3_SVM_REV3_CPU: + return v3_start_svm_guest(core); + break; +#endif +#if V3_CONFIG_VMX + case V3_VMX_CPU: + case V3_VMX_EPT_CPU: + case V3_VMX_EPT_UG_CPU: + return v3_start_vmx_guest(core); + break; +#endif + default: + PrintError(core->vm_info, core, "Attempting to enter a guest on an invalid CPU\n"); + return -1; + } + // should not happen + return 0; +} struct v3_vm_info * v3_create_vm(void * cfg, void * priv_data, char * name) { struct v3_vm_info * vm = v3_config_guest(cfg, priv_data); + int vcore_id = 0; if (vm == NULL) { PrintError(VM_NONE, VCORE_NONE, "Could not configure guest\n"); @@ -299,43 +332,28 @@ struct v3_vm_info * v3_create_vm(void * cfg, void * priv_data, char * name) { PrintError(vm, VCORE_NONE,"Error registering VM with scheduler\n"); } - return vm; -} + for (vcore_id = 0; vcore_id < vm->num_cores; vcore_id++) { + struct guest_info * core = &(vm->cores[vcore_id]); + PrintDebug(vm, VCORE_NONE, "Creating virtual core %u on logical core %u\n", + vcore_id, core->pcpu_id); + sprintf(core->exec_name, "%s-%u", vm->name, vcore_id); -static int start_core(void * p) -{ - struct guest_info * core = (struct guest_info *)p; + PrintDebug(vm, VCORE_NONE, "run: core=%u, func=0x%p, arg=0x%p, name=%s\n", + core->pcpu_id, start_core, core, core->exec_name); - if (v3_scheduler_register_core(core) == -1){ - PrintError(core->vm_info, core,"Error initializing scheduling in core %d\n", core->vcpu_id); - } + core->core_thread = V3_CREATE_THREAD_ON_CPU(core->pcpu_id, start_core, core, core->exec_name); - PrintDebug(core->vm_info,core,"virtual core %u (on logical core %u): in start_core (RIP=%p)\n", - core->vcpu_id, core->pcpu_id, (void *)(addr_t)core->rip); + if (core->core_thread == NULL) { + PrintError(vm, VCORE_NONE, "Thread creation failed\n"); + v3_stop_vm(vm); + return NULL; + } - switch (v3_mach_type) { -#ifdef V3_CONFIG_SVM - case V3_SVM_CPU: - case V3_SVM_REV3_CPU: - return v3_start_svm_guest(core); - break; -#endif -#if V3_CONFIG_VMX - case V3_VMX_CPU: - case V3_VMX_EPT_CPU: - case V3_VMX_EPT_UG_CPU: - return v3_start_vmx_guest(core); - break; -#endif - default: - PrintError(core->vm_info, core, "Attempting to enter a guest on an invalid CPU\n"); - return -1; } - // should not happen - return 0; + return vm; } int v3_start_vm(struct v3_vm_info * vm, unsigned int cpu_mask) { @@ -388,34 +406,23 @@ int v3_start_vm(struct v3_vm_info * vm, unsigned int cpu_mask) { vm->run_state = VM_RUNNING; - for (vcore_id = 0; vcore_id < vm->num_cores; vcore_id++) { struct guest_info * core = &(vm->cores[vcore_id]); PrintDebug(vm, VCORE_NONE, "Starting virtual core %u on logical core %u\n", vcore_id, core->pcpu_id); - - sprintf(core->exec_name, "%s-%u", vm->name, vcore_id); - - PrintDebug(vm, VCORE_NONE, "run: core=%u, func=0x%p, arg=0x%p, name=%s\n", - core->pcpu_id, start_core, core, core->exec_name); - if (core->core_run_state==CORE_INVALID) { + if (core->core_run_state==CORE_INVALID) { // launch of a fresh VM - core->core_run_state = CORE_STOPPED; + core->core_run_state = CORE_STOPPED; // core zero will turn itself on } else { // this is a resume - use whatever its current run_state is } - core->core_thread = V3_CREATE_THREAD_ON_CPU(core->pcpu_id, start_core, core, core->exec_name); + V3_START_THREAD(core->core_thread); - if (core->core_thread == NULL) { - PrintError(vm, VCORE_NONE, "Thread launch failed\n"); - v3_stop_vm(vm); - return -1; - } } return 0;