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.


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