#endif
-
extern struct class * v3_class;
#define STREAM_NAME_LEN 128
#endif
break;
}
+
case V3_VM_STREAM_CONNECT: {
#ifdef V3_CONFIG_STREAM
void __user * argp = (void __user *)arg;
static ssize_t v3_vm_write(struct file * filp, const char __user * buf, size_t size, loff_t * offset) {
-
return 0;
}
};
-
extern int vm_running;
extern u32 pg_allocs;
extern u32 pg_frees;
lock_kernel();
daemonize(guest->name);
-// allow_signal(SIGKILL);
+ // allow_signal(SIGKILL);
unlock_kernel();
if (guest->v3_ctx == NULL) {
printk("palacios: failed to create vm\n");
+ complete(&(guest->start_done));
return -1;
}
printk("Creating VM device: Major %d, Minor %d\n", MAJOR(guest->vm_dev), MINOR(guest->vm_dev));
- cdev_init(&(guest->cdev), &v3_vm_fops);
+ cdev_init(&(guest->cdev), &v3_vm_fops);
guest->cdev.owner = THIS_MODULE;
guest->cdev.ops = &v3_vm_fops;
if (err) {
printk("Fails to add cdev\n");
+ v3_free_vm(guest->v3_ctx);
+ complete(&(guest->start_done));
return -1;
}
if (device_create(v3_class, NULL, guest->vm_dev, guest, "v3-vm%d", MINOR(guest->vm_dev)) == NULL){
printk("Fails to create device\n");
+ cdev_del(&(guest->cdev));
+ v3_free_vm(guest->v3_ctx);
+ complete(&(guest->start_done));
return -1;
}
complete(&(guest->start_done));
- printk("palacios: launching vm\n");
-
+ printk("palacios: launching vm\n");
#if V3_CONFIG_EXT_INSPECTOR
if (v3_start_vm(guest->v3_ctx, 0xffffffff) < 0) {
printk("palacios: launch of vm failed\n");
+ device_destroy(v3_class, guest->vm_dev);
+ cdev_del(&(guest->cdev));
+ v3_free_vm(guest->v3_ctx);
return -1;
}
#include <linux/module.h>
#include <linux/kthread.h>
#include <asm/uaccess.h>
+#include <linux/smp.h>
#include <linux/smp_lock.h>
#include <palacios/vmm.h>
void * arg
)
{
- printk("palacios_xcall: Doing 'xcall' to local cpu\n");
- fn(arg);
- return;
+
+
+ // We set wait to 1, but I'm not sure this is necessary
+ smp_call_function_single(cpu_id, fn, arg, 1);
+
+ return;
}
struct lnx_thread_arg {
thread_info->arg = arg;
thread_info->name = thread_name;
- thread = 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);
return NULL;
}
+ kthread_bind(thread, cpu_id);
+ wake_up_process(thread);
+
return thread;
}
static unsigned int
palacios_get_cpu(void)
{
-#if 1
- return 0;
- // return smp_processor_id();
- // id = get_cpu(); put_cpu(id);
- // return this_cpu;
-#else
- struct cpumask mask;
- unsigned int set;
-
- if(sched_getaffinity(0,&mask)<0){
- panic("sched_getaffinity failed");
- return -1;
- }
- set = cpumask_first(&mask);
- printk("***mask.bits: %d",set);
- return set;
-#endif
+
+ /* We want to call smp_processor_id()
+ * But this is not safe if kernel preemption is possible
+ * We need to ensure that the palacios threads are bound to a give cpu
+ */
+
+ unsigned int cpu_id = get_cpu();
+ put_cpu();
+ return cpu_id;
}
/**
* If it ever changes to induce side effects, we'll need to figure something
* else out...
*/
+
+#include <asm/apic.h>
+
static void
palacios_interrupt_cpu(
struct v3_vm_info * vm,
int vector
)
{
- // panic("palacios_interrupt_cpu");
- // printk("Faking interruption of target CPU by not doing anything since there is only one CPU\n");
- return;
+ if (vector == 0) {
+ smp_send_reschedule(cpu_id);
+ } else {
+ apic->send_IPI_mask(cpumask_of(cpu_id), vector);
+ }
+ return;
}
/**
return 0;
}
+
+
/**
* Acknowledges an interrupt.
*/
palacios_get_cpu_khz(void)
{
printk("cpu_khz is %u\n",cpu_khz);
- if (cpu_khz==0) {
+
+ if (cpu_khz == 0) {
printk("faking cpu_khz to 1000000\n");
return 1000000;
} else {
static void *
palacios_mutex_alloc(void)
{
- spinlock_t *lock = kmalloc(sizeof(spinlock_t), GFP_KERNEL);
- if (lock)
- spin_lock_init(lock);
- return lock;
+ spinlock_t *lock = kmalloc(sizeof(spinlock_t), GFP_KERNEL);
+
+ if (lock) {
+ spin_lock_init(lock);
+ }
+
+ return lock;
}
/**
* Frees a mutex.
*/
static void
-palacios_mutex_free(
- void * mutex
-)
-{
- kfree(mutex);
+palacios_mutex_free(void * mutex) {
+ kfree(mutex);
}
/**
* Locks a mutex.
*/
static void
-palacios_mutex_lock(
- void * mutex,
- int must_spin
-)
-{
- spin_lock((spinlock_t*)mutex);
+palacios_mutex_lock(void * mutex, int must_spin) {
+ spin_lock((spinlock_t *)mutex);
}
/**
void * mutex
)
{
- spin_unlock((spinlock_t*)mutex);
+ spin_unlock((spinlock_t *)mutex);
}
/**
printk("palacios_init starting - calling init_v3\n");
- Init_V3(&palacios_os_hooks, 1);
-
+ Init_V3(&palacios_os_hooks, nr_cpu_ids);
return 0;