extern unsigned int cpu_khz;
+extern int cpu_list[NR_CPUS];
+extern int cpu_list_len;
+
/**
* Prints a message to the console.
addr = kmalloc(size, GFP_KERNEL);
}
mallocs++;
+
return addr;
}
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);
+ INFO("Daemonizing new Palacios thread (name=%s)\n", thread_info->name);
daemonize(thread_info->name);
allow_signal(SIGKILL);
*/
- thread_info->fn(thread_info->arg);
+ ret = thread_info->fn(thread_info->arg);
kfree(thread_info);
// handle cleanup
+
- return 0;
+ printk("Palacios Thread (%s) EXITTING\n", thread_info->name);
+
+ do_exit(ret);
+
+ return 0; // should not get here.
}
/**
* Creates a kernel thread.
*/
-static void
+static void *
palacios_start_kernel_thread(
int (*fn) (void * arg),
void * arg,
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 );
}
thread = kthread_create( lnx_thread_target, thread_info, thread_name );
if (IS_ERR(thread)) {
- printk("Palacios error creating thread: %s\n", thread_name);
+ WARNING("Palacios error creating thread: %s\n", thread_name);
+ return NULL;
+ }
+
+ if (set_cpus_allowed_ptr(thread, cpumask_of(cpu_id)) != 0) {
+ kthread_stop(thread);
return NULL;
}
- kthread_bind(thread, cpu_id);
wake_up_process(thread);
return thread;
*/
static int
palacios_move_thread_to_cpu(int new_cpu_id,
- void * thread_ptr) {
+ void * thread_ptr) {
struct task_struct * thread = (struct task_struct *)thread_ptr;
- if(thread == NULL){
+ INFO("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(thread, cpumask_of_cpu(new_cpu_id));
+ return set_cpus_allowed_ptr(thread, cpumask_of(new_cpu_id));
}
static int
palacios_hook_interrupt(struct v3_vm_info * vm,
unsigned int vector ) {
- printk("hooking vector %d\n", vector);
+ INFO("hooking vector %d\n", vector);
if (irq_to_guest_map[vector]) {
- printk(KERN_WARNING
+ WARNING(
"%s: Interrupt vector %u is already hooked.\n",
__func__, vector);
return -1;
}
- printk(KERN_DEBUG
+ DEBUG(
"%s: Hooking interrupt vector %u to vm %p.\n",
__func__, vector, vm);
int flag = 0;
int error;
- printk("hooking vector: %d\n", vector);
+ DEBUG("hooking vector: %d\n", vector);
if (vector == 32) {
flag = IRQF_TIMER;
&device_id);
if (error) {
- printk("error code for request_irq is %d\n", error);
+ ERROR("error code for request_irq is %d\n", error);
panic("request vector %d failed",vector);
}
}
)
{
ack_APIC_irq();
- printk("Pretending to ack interrupt, vector=%d\n",vector);
+ DEBUG("Pretending to ack interrupt, vector=%d\n",vector);
return 0;
}
static unsigned int
palacios_get_cpu_khz(void)
{
- printk("cpu_khz is %u\n",cpu_khz);
+ INFO("cpu_khz is %u\n",cpu_khz);
if (cpu_khz == 0) {
- printk("faking cpu_khz to 1000000\n");
+ INFO("faking cpu_khz to 1000000\n");
return 1000000;
} else {
return cpu_khz;
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) {
+ WARNING("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);
+
+ INFO("palacios_init starting - calling init_v3\n");
- 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;