X-Git-Url: http://v3vee.org/palacios/gitweb/gitweb.cgi?a=blobdiff_plain;f=linux_module%2Fpalacios-stubs.c;h=c5b0ca0f5680f2494ea1e8df16e912ffe7d571f3;hb=a2b48dd0c4f8ccfa633139bc2b9aa4ddf59eda5c;hp=0310a408cfc26a0be28629727741a5e322629530;hpb=6cf74ab2b04c8af061a637e50b3241e365d40aa3;p=palacios.git diff --git a/linux_module/palacios-stubs.c b/linux_module/palacios-stubs.c index 0310a40..c5b0ca0 100644 --- a/linux_module/palacios-stubs.c +++ b/linux_module/palacios-stubs.c @@ -36,6 +36,9 @@ static struct v3_vm_info * irq_to_guest_map[256]; extern unsigned int cpu_khz; +extern int cpu_list[NR_CPUS]; +extern int cpu_list_len; + /** * Prints a message to the console. @@ -91,6 +94,7 @@ palacios_alloc(unsigned int size) { addr = kmalloc(size, GFP_KERNEL); } mallocs++; + return addr; } @@ -154,12 +158,11 @@ palacios_xcall( struct lnx_thread_arg { int (*fn)(void * arg); void * arg; - char * name; }; static int lnx_thread_target(void * arg) { struct lnx_thread_arg * thread_info = (struct lnx_thread_arg *)arg; - + int ret = 0; /* printk("Daemonizing new Palacios thread (name=%s)\n", thread_info->name); @@ -168,18 +171,20 @@ static int lnx_thread_target(void * arg) { */ - thread_info->fn(thread_info->arg); + ret = thread_info->fn(thread_info->arg); kfree(thread_info); // handle cleanup + + do_exit(ret); - return 0; + return 0; // should not get here. } /** * Creates a kernel thread. */ -static void +static void * palacios_start_kernel_thread( int (*fn) (void * arg), void * arg, @@ -189,10 +194,8 @@ palacios_start_kernel_thread( thread_info->fn = fn; thread_info->arg = arg; - thread_info->name = thread_name; - kthread_run( lnx_thread_target, thread_info, thread_name ); - return; + return kthread_run( lnx_thread_target, thread_info, thread_name ); } @@ -209,7 +212,6 @@ palacios_start_thread_on_cpu(int cpu_id, thread_info->fn = fn; thread_info->arg = arg; - thread_info->name = thread_name; thread = kthread_create( lnx_thread_target, thread_info, thread_name ); @@ -219,12 +221,41 @@ palacios_start_thread_on_cpu(int cpu_id, return NULL; } - kthread_bind(thread, cpu_id); + if (set_cpus_allowed_ptr(thread, cpumask_of(cpu_id)) != 0) { + kthread_stop(thread); + return NULL; + } + wake_up_process(thread); return thread; } + +/** + * Rebind a kernel thread to the specified CPU + * The thread will be running on target CPU on return + * non-zero return means failure + */ +static int +palacios_move_thread_to_cpu(int new_cpu_id, + void * thread_ptr) { + struct task_struct * thread = (struct task_struct *)thread_ptr; + + printk("Moving thread (%p) to cpu %d\n", thread, new_cpu_id); + + if (thread == NULL) { + thread = current; + } + + /* + * Bind to the specified CPU. When this call returns, + * the thread should be running on the target CPU. + */ + return set_cpus_allowed_ptr(thread, cpumask_of(new_cpu_id)); +} + + /** * Returns the CPU ID that the caller is running on. */ @@ -460,6 +491,7 @@ static struct v3_os_hooks palacios_os_hooks = { .interrupt_cpu = palacios_interrupt_cpu, .call_on_cpu = palacios_xcall, .start_thread_on_cpu = palacios_start_thread_on_cpu, + .move_thread_to_cpu = palacios_move_thread_to_cpu, }; @@ -467,12 +499,35 @@ static struct v3_os_hooks palacios_os_hooks = { int palacios_vmm_init( void ) { + int num_cpus = num_online_cpus(); + char * cpu_mask = NULL; + + if (cpu_list_len > 0) { + int major = 0; + int minor = 0; + int i = 0; + + cpu_mask = kmalloc((num_cpus / 8) + 1, GFP_KERNEL); + memset(cpu_mask, 0, (num_cpus / 8) + 1); + + for (i = 0; i < cpu_list_len; i++) { + if (cpu_list[i] >= num_cpus) { + printk("CPU (%d) exceeds number of available CPUs. Ignoring...\n", cpu_list[i]); + continue; + } + + major = cpu_list[i] / 8; + minor = cpu_list[i] % 8; + *(cpu_mask + major) |= (0x1 << minor); + } + } + memset(irq_to_guest_map, 0, sizeof(struct v3_vm_info *) * 256); - + printk("palacios_init starting - calling init_v3\n"); - Init_V3(&palacios_os_hooks, nr_cpu_ids); + Init_V3(&palacios_os_hooks, cpu_mask, num_cpus); return 0;