Palacios Public Git Repository

To checkout Palacios execute

  git clone http://v3vee.org/palacios/palacios.web/palacios.git
This will give you the master branch. You probably want the devel branch or one of the release branches. To switch to the devel branch, simply execute
  cd palacios
  git checkout --track -b devel origin/devel
The other branches are similar.


Added updated sleep/wakeup functionality
[palacios.git] / linux_module / palacios-stubs.c
1 #include <linux/kernel.h>
2 #include <linux/kthread.h>
3 #include <linux/spinlock.h>
4 #include <linux/gfp.h>
5 #include <linux/interrupt.h>
6 #include <linux/linkage.h>
7 #include <linux/sched.h>
8 #include <linux/uaccess.h>
9 #include <asm/irq_vectors.h>
10 #include <asm/io.h>
11
12 #include <linux/init.h>
13 #include <linux/module.h>
14 #include <linux/kthread.h>
15 #include <asm/uaccess.h>
16 #include <linux/smp.h>
17
18 #include <palacios/vmm.h>
19 #include <palacios/vmm_host_events.h>
20 #include "palacios.h"
21
22
23
24
25 #include "mm.h"
26
27 // The following can be used to track heap bugs
28 // zero memory after allocation
29 #define ALLOC_ZERO_MEM 0
30 // pad allocations by this many bytes on both ends of block
31 #define ALLOC_PAD      0
32
33
34 u32 pg_allocs = 0;
35 u32 pg_frees = 0;
36 u32 mallocs = 0;
37 u32 frees = 0;
38
39
40 static struct v3_vm_info * irq_to_guest_map[256];
41
42
43 extern unsigned int cpu_khz;
44
45 extern int cpu_list[NR_CPUS];
46 extern int cpu_list_len;
47
48
49 static char *print_buffer[NR_CPUS];
50
51 static void deinit_print_buffers(void)
52 {
53     int i;
54
55     for (i=0;i<NR_CPUS;i++) {
56         if (print_buffer[i]) { 
57             palacios_free(print_buffer[i]);
58             print_buffer[i]=0;
59         }
60     }
61 }
62
63 static int init_print_buffers(void)
64 {
65     int i;
66     
67     memset(print_buffer,0,sizeof(char*)*NR_CPUS);
68
69 #if !V3_PRINTK_OLD_STYLE_OUTPUT
70
71     for (i=0;i<NR_CPUS;i++) { 
72         print_buffer[i] = palacios_alloc(V3_PRINTK_BUF_SIZE);
73         if (!print_buffer[i]) { 
74             ERROR("Cannot allocate print buffer for cpu %d\n",i);
75             deinit_print_buffers();
76             return -1;
77         }
78         memset(print_buffer[i],0,V3_PRINTK_BUF_SIZE);
79     }
80
81 #endif
82     
83     return 0;
84
85 }
86  
87 /**
88  * Prints a message to the console.
89  */
90 void palacios_print(const char *fmt, ...) {
91
92 #if V3_PRINTK_OLD_STYLE_OUTPUT
93
94   va_list ap;
95
96   va_start(ap, fmt);
97   vprintk(fmt, ap);
98   va_end(ap);
99
100   return
101
102 #else 
103
104   va_list ap;
105   char *buf;
106   unsigned int cpu = palacios_get_cpu();
107
108   buf = print_buffer[cpu];
109
110   if (!buf) { 
111       printk(KERN_INFO "palacios (pcore %u): output skipped - no allocated buffer\n",cpu);
112       return;
113   } 
114
115   va_start(ap, fmt);
116   vsnprintf(buf,V3_PRINTK_BUF_SIZE, fmt, ap);
117   va_end(ap);
118
119 #if V3_PRINTK_CHECK_7BIT
120   {
121       char c=0;
122       int i;
123       for (i=0;i<strlen(buf);i++) { 
124           if (buf[i] < 0) {
125               c=buf[i];
126               break;
127           }
128       }
129       if (c!=0) { 
130           printk(KERN_INFO "palacios (pcore %u): ALERT ALERT 8 BIT CHAR (c=%d) DETECTED\n", cpu,c);
131       }
132   }
133 #endif
134
135   printk(KERN_INFO "palacios (pcore %u): %s",cpu,buf);
136
137   return;
138
139 #endif
140
141 }
142
143
144
145 /*
146  * Allocates a contiguous region of pages of the requested size.
147  * Returns the physical address of the first page in the region.
148  */
149 void *palacios_allocate_pages(int num_pages, unsigned int alignment) {
150     void * pg_addr = NULL;
151
152     pg_addr = (void *)alloc_palacios_pgs(num_pages, alignment);
153
154     if (!pg_addr) { 
155         ERROR("ALERT ALERT  Page allocation has FAILED Warning\n");
156         return NULL;
157     }
158
159     pg_allocs += num_pages;
160
161     return pg_addr;
162 }
163
164
165 /**
166  * Frees a page previously allocated via palacios_allocate_page().
167  * Note that palacios_allocate_page() can allocate multiple pages with
168  * a single call while palacios_free_page() only frees a single page.
169  */
170
171 void palacios_free_pages(void * page_paddr, int num_pages) {
172     pg_frees += num_pages;
173     free_palacios_pgs((uintptr_t)page_paddr, num_pages);
174 }
175
176
177 void *
178 palacios_alloc_extended(unsigned int size, unsigned int flags) {
179     void * addr = NULL;
180
181     addr = kmalloc(size+2*ALLOC_PAD, flags);
182
183     if (!addr) { 
184        ERROR("ALERT ALERT  kmalloc has FAILED FAILED FAILED\n");
185        return NULL;
186     }   
187
188     mallocs++;
189
190 #if ALLOC_ZERO_MEM
191     memset(addr,0,size+2*ALLOC_PAD);
192 #endif
193
194     return addr+ALLOC_PAD;
195 }
196
197
198 /**
199  * Allocates 'size' bytes of kernel memory.
200  * Returns the kernel virtual address of the memory allocated.
201  */
202 void *
203 palacios_alloc(unsigned int size) {
204
205     // It is very important that this test remains since 
206     // this function is used extensively throughout palacios and the linux
207     // module, both in places where interrupts are off and where they are on
208     // a GFP_KERNEL call, when done with interrupts off can lead to DEADLOCK
209     if (irqs_disabled()) {
210         return palacios_alloc_extended(size,GFP_ATOMIC);
211     } else {
212         return palacios_alloc_extended(size,GFP_KERNEL);
213     }
214
215 }
216
217 /**
218  * Frees memory that was previously allocated by palacios_alloc().
219  */
220 void
221 palacios_free(
222         void *                  addr
223 )
224 {
225     frees++;
226     kfree(addr-ALLOC_PAD);
227     return;
228 }
229
230 /**
231  * Converts a kernel virtual address to the corresponding physical address.
232  */
233 void *
234 palacios_vaddr_to_paddr(
235         void *                  vaddr
236 )
237 {
238     return (void*) __pa(vaddr);
239
240 }
241
242 /**
243  * Converts a physical address to the corresponding kernel virtual address.
244  */
245 void *
246 palacios_paddr_to_vaddr(
247         void *                  paddr
248 )
249 {
250   return __va(paddr);
251 }
252
253 /**
254  * Runs a function on the specified CPU.
255  */
256 static void 
257 palacios_xcall(
258         int                     cpu_id, 
259         void                    (*fn)(void *arg),
260         void *                  arg
261 )
262 {
263
264
265     // We set wait to 1, but I'm not sure this is necessary
266     smp_call_function_single(cpu_id, fn, arg, 1);
267     
268     return;
269 }
270
271
272 #define MAX_THREAD_NAME 32
273
274 struct lnx_thread_arg {
275     int (*fn)(void * arg);
276     void * arg;
277     char name[MAX_THREAD_NAME];
278 };
279
280 static int lnx_thread_target(void * arg) {
281     struct lnx_thread_arg * thread_info = (struct lnx_thread_arg *)arg;
282     int ret = 0;
283     /*
284       INFO("Daemonizing new Palacios thread (name=%s)\n", thread_info->name);
285
286       daemonize(thread_info->name);
287       allow_signal(SIGKILL);
288     */
289
290
291     ret = thread_info->fn(thread_info->arg);
292
293
294     INFO("Palacios Thread (%s) EXITING\n", thread_info->name);
295
296     palacios_free(thread_info);
297     // handle cleanup 
298
299     do_exit(ret);
300     
301     return 0; // should not get here.
302 }
303
304 /**
305  * Creates a kernel thread.
306  */
307 void *
308 palacios_start_kernel_thread(
309         int (*fn)               (void * arg),
310         void *                  arg,
311         char *                  thread_name) {
312
313     struct lnx_thread_arg * thread_info = palacios_alloc(sizeof(struct lnx_thread_arg));
314
315     if (!thread_info) { 
316         ERROR("ALERT ALERT Unable to allocate thread\n");
317         return NULL;
318     }
319
320     thread_info->fn = fn;
321     thread_info->arg = arg;
322     strncpy(thread_info->name,thread_name,MAX_THREAD_NAME);
323     thread_info->name[MAX_THREAD_NAME-1] =0;
324
325     return kthread_run( lnx_thread_target, thread_info, thread_info->name );
326 }
327
328
329 /**
330  * Starts a kernel thread on the specified CPU.
331  */
332 void * 
333 palacios_start_thread_on_cpu(int cpu_id, 
334                              int (*fn)(void * arg), 
335                              void * arg, 
336                              char * thread_name ) {
337     struct task_struct * thread = NULL;
338     struct lnx_thread_arg * thread_info = palacios_alloc(sizeof(struct lnx_thread_arg));
339
340     if (!thread_info) { 
341         ERROR("ALERT ALERT Unable to allocate thread to start on cpu\n");
342         return NULL;
343     }
344
345     thread_info->fn = fn;
346     thread_info->arg = arg;
347     strncpy(thread_info->name,thread_name,MAX_THREAD_NAME);
348     thread_info->name[MAX_THREAD_NAME-1] =0;
349
350     thread = kthread_create( lnx_thread_target, thread_info, thread_info->name );
351
352     if (IS_ERR(thread)) {
353         WARNING("Palacios error creating thread: %s\n", thread_info->name);
354         palacios_free(thread_info);
355         return NULL;
356     }
357
358     if (set_cpus_allowed_ptr(thread, cpumask_of(cpu_id)) != 0) {
359         WARNING("Attempt to start thread on disallowed CPU\n");
360         kthread_stop(thread);
361         palacios_free(thread_info);
362         return NULL;
363     }
364
365     wake_up_process(thread);
366
367     return thread;
368 }
369
370
371 /**
372  * Rebind a kernel thread to the specified CPU
373  * The thread will be running on target CPU on return
374  * non-zero return means failure
375  */
376 int
377 palacios_move_thread_to_cpu(int new_cpu_id, 
378                             void * thread_ptr) {
379     struct task_struct * thread = (struct task_struct *)thread_ptr;
380
381     INFO("Moving thread (%p) to cpu %d\n", thread, new_cpu_id);
382
383     if (thread == NULL) {
384         thread = current;
385     }
386
387     /*
388      * Bind to the specified CPU.  When this call returns,
389      * the thread should be running on the target CPU.
390      */
391     return set_cpus_allowed_ptr(thread, cpumask_of(new_cpu_id));
392 }
393
394
395 /**
396  * Returns the CPU ID that the caller is running on.
397  */
398 unsigned int 
399 palacios_get_cpu(void) 
400 {
401
402     /* We want to call smp_processor_id()
403      * But this is not safe if kernel preemption is possible 
404      * We need to ensure that the palacios threads are bound to a give cpu
405      */
406
407     unsigned int cpu_id = get_cpu(); 
408     put_cpu();
409     return cpu_id;
410 }
411
412 /**
413  * Interrupts the physical CPU corresponding to the specified logical guest cpu.
414  *
415  * NOTE: 
416  * This is dependent on the implementation of xcall_reschedule().  Currently
417  * xcall_reschedule does not explicitly call schedule() on the destination CPU,
418  * but instead relies on the return to user space to handle it. Because
419  * palacios is a kernel thread schedule will not be called, which is correct.
420  * If it ever changes to induce side effects, we'll need to figure something
421  * else out...
422  */
423
424 #include <asm/apic.h>
425
426 static void
427 palacios_interrupt_cpu(
428         struct v3_vm_info *     vm, 
429         int                     cpu_id, 
430         int                     vector
431 )
432 {
433     if (vector == 0) {
434         smp_send_reschedule(cpu_id);
435     } else {
436         apic->send_IPI_mask(cpumask_of(cpu_id), vector);
437     }
438     return;
439 }
440
441 /**
442  * Dispatches an interrupt to Palacios for handling.
443  */
444 static void
445 palacios_dispatch_interrupt( int vector, void * dev, struct pt_regs * regs ) {
446     struct v3_interrupt intr = {
447         .irq            = vector,
448         .error          = regs->orig_ax,
449         .should_ack     = 1,
450     };
451     
452     if (irq_to_guest_map[vector]) {
453         v3_deliver_irq(irq_to_guest_map[vector], &intr);
454     }
455     
456 }
457
458 /**
459  * Instructs the kernel to forward the specified IRQ to Palacios.
460  */
461 static int
462 palacios_hook_interrupt(struct v3_vm_info *     vm,
463                         unsigned int            vector ) {
464     INFO("hooking vector %d\n", vector);        
465
466     if (irq_to_guest_map[vector]) {
467         WARNING(
468                "%s: Interrupt vector %u is already hooked.\n",
469                __func__, vector);
470         return -1;
471     }
472
473     DEBUG(
474            "%s: Hooking interrupt vector %u to vm %p.\n",
475            __func__, vector, vm);
476
477     irq_to_guest_map[vector] = vm;
478
479     /*
480      * NOTE: Normally PCI devices are supposed to be level sensitive,
481      *       but we need them to be edge sensitive so that they are
482      *       properly latched by Palacios.  Leaving them as level
483      *       sensitive would lead to an interrupt storm.
484      */
485     //ioapic_set_trigger_for_vector(vector, ioapic_edge_sensitive);
486     
487     //set_idtvec_handler(vector, palacios_dispatch_interrupt);
488     if (vector < 32) {
489         ERROR("unexpected vector for hooking\n");
490         return -1;
491     } else {
492         int device_id = 0;              
493         
494         int flag = 0;
495         int error;
496                 
497         DEBUG("hooking vector: %d\n", vector);          
498
499         if (vector == 32) {
500             flag = IRQF_TIMER;
501         } else {
502             flag = IRQF_SHARED;
503         }
504
505         error = request_irq((vector - 32),
506                             (void *)palacios_dispatch_interrupt,
507                             flag,
508                             "interrupt_for_palacios",
509                             &device_id);
510         
511         if (error) {
512             ERROR("error code for request_irq is %d\n", error);
513             ERROR("request vector %d failed", vector);
514             return -1;
515         }
516     }
517         
518     return 0;
519 }
520
521
522
523 /**
524  * Acknowledges an interrupt.
525  */
526 static int
527 palacios_ack_interrupt(
528         int                     vector
529
530 {
531   ack_APIC_irq(); 
532   DEBUG("Pretending to ack interrupt, vector=%d\n", vector);
533   return 0;
534 }
535   
536 /**
537  * Returns the CPU frequency in kilohertz.
538  */
539 unsigned int
540 palacios_get_cpu_khz(void) 
541 {
542     INFO("cpu_khz is %u\n", cpu_khz);
543
544     if (cpu_khz == 0) { 
545         INFO("faking cpu_khz to 1000000\n");
546         return 1000000;
547     } else {
548         return cpu_khz;
549     }
550   //return 1000000;
551 }
552
553 /**
554  * Yield the CPU so other host OS tasks can run.
555  * This will return immediately if there is no other thread that is runnable
556  * And there is no real bound on how long it will yield
557  */
558 void
559 palacios_yield_cpu(void)
560 {
561     schedule();
562     return;
563 }
564
565 /**
566  * Yield the CPU so other host OS tasks can run.
567  * Given now immediately if there is no other thread that is runnable
568  * And there is no real bound on how long it will yield
569  */
570 void palacios_sleep_cpu(unsigned int us)
571 {
572
573     set_current_state(TASK_INTERRUPTIBLE);
574     if (us) {
575         unsigned int uspj = 1000000U/HZ;
576         unsigned int jiffies = us/uspj + ((us%uspj) !=0);  // ceiling 
577         schedule_timeout(jiffies);
578     } else {
579         schedule();
580     }
581     return;
582 }
583
584 void palacios_wakeup_cpu(void *thread)
585 {
586     wake_up_process(thread);
587     return;
588 }
589
590 /**
591  * Allocates a mutex.
592  * Returns NULL on failure.
593  */
594 void *
595 palacios_mutex_alloc(void)
596 {
597     spinlock_t *lock = palacios_alloc(sizeof(spinlock_t));
598
599     if (lock) {
600         spin_lock_init(lock);
601     } else {
602         ERROR("ALERT ALERT Unable to allocate lock\n");
603         return NULL;
604     }
605     
606     return lock;
607 }
608
609 /**
610  * Frees a mutex.
611  */
612 void
613 palacios_mutex_free(void * mutex) {
614     palacios_free(mutex);
615 }
616
617 /**
618  * Locks a mutex.
619  */
620 void 
621 palacios_mutex_lock(void * mutex, int must_spin) {
622     spin_lock((spinlock_t *)mutex);
623 }
624
625
626 /**
627  * Locks a mutex, disabling interrupts on this core
628  */
629 void *
630 palacios_mutex_lock_irqsave(void * mutex, int must_spin) {
631     
632     unsigned long flags; 
633     
634     spin_lock_irqsave((spinlock_t *)mutex,flags);
635
636     return (void *)flags;
637 }
638
639
640 /**
641  * Unlocks a mutex.
642  */
643 void 
644 palacios_mutex_unlock(
645         void *                  mutex
646
647 {
648     spin_unlock((spinlock_t *)mutex);
649 }
650
651
652 /**
653  * Unlocks a mutex and restores previous interrupt state on this core
654  */
655 void 
656 palacios_mutex_unlock_irqrestore(void *mutex, void *flags)
657 {
658     // This is correct, flags is opaque
659     spin_unlock_irqrestore((spinlock_t *)mutex,(unsigned long)flags);
660 }
661
662 /**
663  * Structure used by the Palacios hypervisor to interface with the host kernel.
664  */
665 static struct v3_os_hooks palacios_os_hooks = {
666         .print                  = palacios_print,
667         .allocate_pages         = palacios_allocate_pages,
668         .free_pages             = palacios_free_pages,
669         .malloc                 = palacios_alloc,
670         .free                   = palacios_free,
671         .vaddr_to_paddr         = palacios_vaddr_to_paddr,
672         .paddr_to_vaddr         = palacios_paddr_to_vaddr,
673         .hook_interrupt         = palacios_hook_interrupt,
674         .ack_irq                = palacios_ack_interrupt,
675         .get_cpu_khz            = palacios_get_cpu_khz,
676         .start_kernel_thread    = palacios_start_kernel_thread,
677         .yield_cpu              = palacios_yield_cpu,
678         .sleep_cpu              = palacios_sleep_cpu,
679         .wakeup_cpu             = palacios_wakeup_cpu,
680         .mutex_alloc            = palacios_mutex_alloc,
681         .mutex_free             = palacios_mutex_free,
682         .mutex_lock             = palacios_mutex_lock, 
683         .mutex_unlock           = palacios_mutex_unlock,
684         .mutex_lock_irqsave     = palacios_mutex_lock_irqsave, 
685         .mutex_unlock_irqrestore= palacios_mutex_unlock_irqrestore,
686         .get_cpu                = palacios_get_cpu,
687         .interrupt_cpu          = palacios_interrupt_cpu,
688         .call_on_cpu            = palacios_xcall,
689         .start_thread_on_cpu    = palacios_start_thread_on_cpu,
690         .move_thread_to_cpu     = palacios_move_thread_to_cpu,
691 };
692
693
694
695
696 int palacios_vmm_init( void )
697 {
698     int num_cpus = num_online_cpus();
699     char * cpu_mask = NULL;
700
701     if (cpu_list_len > 0) {
702         int major = 0;
703         int minor = 0;
704         int i = 0;
705
706         cpu_mask = palacios_alloc((num_cpus / 8) + 1);
707
708         if (!cpu_mask) { 
709             ERROR("Cannot allocate cpu mask\n");
710             return -1;
711         }
712
713         memset(cpu_mask, 0, (num_cpus / 8) + 1);
714         
715         for (i = 0; i < cpu_list_len; i++) {
716             if (cpu_list[i] >= num_cpus) {
717                 WARNING("CPU (%d) exceeds number of available CPUs. Ignoring...\n", cpu_list[i]);
718                 continue;
719             }
720
721             major = cpu_list[i] / 8;
722             minor = cpu_list[i] % 8;
723     
724             *(cpu_mask + major) |= (0x1 << minor);
725         }
726     }
727
728     memset(irq_to_guest_map, 0, sizeof(struct v3_vm_info *) * 256);
729
730     if (init_print_buffers()) {
731         ERROR("Cannot initialize print buffers\n");
732         palacios_free(cpu_mask);
733         return -1;
734     }
735
736     INFO("palacios_init starting - calling init_v3\n");
737
738     Init_V3(&palacios_os_hooks, cpu_mask, num_cpus);
739
740     return 0;
741
742 }
743
744
745 int palacios_vmm_exit( void ) {
746
747     Shutdown_V3();
748
749     INFO("palacios shutdown complete\n");
750
751     deinit_print_buffers();
752
753     return 0;
754 }