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.


Expose kmalloc flags within linux_module + add further debugging features for heap...
[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 struct lnx_thread_arg {
272     int (*fn)(void * arg);
273     void * arg;
274     char * name;
275 };
276
277 static int lnx_thread_target(void * arg) {
278     struct lnx_thread_arg * thread_info = (struct lnx_thread_arg *)arg;
279     int ret = 0;
280     /*
281       INFO("Daemonizing new Palacios thread (name=%s)\n", thread_info->name);
282
283       daemonize(thread_info->name);
284       allow_signal(SIGKILL);
285     */
286
287
288     ret = thread_info->fn(thread_info->arg);
289
290
291     INFO("Palacios Thread (%s) EXITING\n", thread_info->name);
292
293     palacios_free(thread_info);
294     // handle cleanup 
295
296     do_exit(ret);
297     
298     return 0; // should not get here.
299 }
300
301 /**
302  * Creates a kernel thread.
303  */
304 void *
305 palacios_start_kernel_thread(
306         int (*fn)               (void * arg),
307         void *                  arg,
308         char *                  thread_name) {
309
310     struct lnx_thread_arg * thread_info = palacios_alloc(sizeof(struct lnx_thread_arg));
311
312     if (!thread_info) { 
313         ERROR("ALERT ALERT Unable to allocate thread\n");
314         return NULL;
315     }
316
317     thread_info->fn = fn;
318     thread_info->arg = arg;
319     thread_info->name = thread_name;
320
321     return kthread_run( lnx_thread_target, thread_info, thread_name );
322 }
323
324
325 /**
326  * Starts a kernel thread on the specified CPU.
327  */
328 void * 
329 palacios_start_thread_on_cpu(int cpu_id, 
330                              int (*fn)(void * arg), 
331                              void * arg, 
332                              char * thread_name ) {
333     struct task_struct * thread = NULL;
334     struct lnx_thread_arg * thread_info = palacios_alloc(sizeof(struct lnx_thread_arg));
335
336     if (!thread_info) { 
337         ERROR("ALERT ALERT Unable to allocate thread to start on cpu\n");
338         return NULL;
339     }
340
341     thread_info->fn = fn;
342     thread_info->arg = arg;
343     thread_info->name = thread_name;
344
345
346     thread = kthread_create( lnx_thread_target, thread_info, thread_name );
347
348     if (IS_ERR(thread)) {
349         WARNING("Palacios error creating thread: %s\n", thread_name);
350         palacios_free(thread_info);
351         return NULL;
352     }
353
354     if (set_cpus_allowed_ptr(thread, cpumask_of(cpu_id)) != 0) {
355         WARNING("Attempt to start thread on disallowed CPU\n");
356         kthread_stop(thread);
357         palacios_free(thread_info);
358         return NULL;
359     }
360
361     wake_up_process(thread);
362
363     return thread;
364 }
365
366
367 /**
368  * Rebind a kernel thread to the specified CPU
369  * The thread will be running on target CPU on return
370  * non-zero return means failure
371  */
372 int
373 palacios_move_thread_to_cpu(int new_cpu_id, 
374                             void * thread_ptr) {
375     struct task_struct * thread = (struct task_struct *)thread_ptr;
376
377     INFO("Moving thread (%p) to cpu %d\n", thread, new_cpu_id);
378
379     if (thread == NULL) {
380         thread = current;
381     }
382
383     /*
384      * Bind to the specified CPU.  When this call returns,
385      * the thread should be running on the target CPU.
386      */
387     return set_cpus_allowed_ptr(thread, cpumask_of(new_cpu_id));
388 }
389
390
391 /**
392  * Returns the CPU ID that the caller is running on.
393  */
394 unsigned int 
395 palacios_get_cpu(void) 
396 {
397
398     /* We want to call smp_processor_id()
399      * But this is not safe if kernel preemption is possible 
400      * We need to ensure that the palacios threads are bound to a give cpu
401      */
402
403     unsigned int cpu_id = get_cpu(); 
404     put_cpu();
405     return cpu_id;
406 }
407
408 /**
409  * Interrupts the physical CPU corresponding to the specified logical guest cpu.
410  *
411  * NOTE: 
412  * This is dependent on the implementation of xcall_reschedule().  Currently
413  * xcall_reschedule does not explicitly call schedule() on the destination CPU,
414  * but instead relies on the return to user space to handle it. Because
415  * palacios is a kernel thread schedule will not be called, which is correct.
416  * If it ever changes to induce side effects, we'll need to figure something
417  * else out...
418  */
419
420 #include <asm/apic.h>
421
422 static void
423 palacios_interrupt_cpu(
424         struct v3_vm_info *     vm, 
425         int                     cpu_id, 
426         int                     vector
427 )
428 {
429     if (vector == 0) {
430         smp_send_reschedule(cpu_id);
431     } else {
432         apic->send_IPI_mask(cpumask_of(cpu_id), vector);
433     }
434     return;
435 }
436
437 /**
438  * Dispatches an interrupt to Palacios for handling.
439  */
440 static void
441 palacios_dispatch_interrupt( int vector, void * dev, struct pt_regs * regs ) {
442     struct v3_interrupt intr = {
443         .irq            = vector,
444         .error          = regs->orig_ax,
445         .should_ack     = 1,
446     };
447     
448     if (irq_to_guest_map[vector]) {
449         v3_deliver_irq(irq_to_guest_map[vector], &intr);
450     }
451     
452 }
453
454 /**
455  * Instructs the kernel to forward the specified IRQ to Palacios.
456  */
457 static int
458 palacios_hook_interrupt(struct v3_vm_info *     vm,
459                         unsigned int            vector ) {
460     INFO("hooking vector %d\n", vector);        
461
462     if (irq_to_guest_map[vector]) {
463         WARNING(
464                "%s: Interrupt vector %u is already hooked.\n",
465                __func__, vector);
466         return -1;
467     }
468
469     DEBUG(
470            "%s: Hooking interrupt vector %u to vm %p.\n",
471            __func__, vector, vm);
472
473     irq_to_guest_map[vector] = vm;
474
475     /*
476      * NOTE: Normally PCI devices are supposed to be level sensitive,
477      *       but we need them to be edge sensitive so that they are
478      *       properly latched by Palacios.  Leaving them as level
479      *       sensitive would lead to an interrupt storm.
480      */
481     //ioapic_set_trigger_for_vector(vector, ioapic_edge_sensitive);
482     
483     //set_idtvec_handler(vector, palacios_dispatch_interrupt);
484     if (vector < 32) {
485         ERROR("unexpected vector for hooking\n");
486         return -1;
487     } else {
488         int device_id = 0;              
489         
490         int flag = 0;
491         int error;
492                 
493         DEBUG("hooking vector: %d\n", vector);          
494
495         if (vector == 32) {
496             flag = IRQF_TIMER;
497         } else {
498             flag = IRQF_SHARED;
499         }
500
501         error = request_irq((vector - 32),
502                             (void *)palacios_dispatch_interrupt,
503                             flag,
504                             "interrupt_for_palacios",
505                             &device_id);
506         
507         if (error) {
508             ERROR("error code for request_irq is %d\n", error);
509             ERROR("request vector %d failed", vector);
510             return -1;
511         }
512     }
513         
514     return 0;
515 }
516
517
518
519 /**
520  * Acknowledges an interrupt.
521  */
522 static int
523 palacios_ack_interrupt(
524         int                     vector
525
526 {
527   ack_APIC_irq(); 
528   DEBUG("Pretending to ack interrupt, vector=%d\n", vector);
529   return 0;
530 }
531   
532 /**
533  * Returns the CPU frequency in kilohertz.
534  */
535 unsigned int
536 palacios_get_cpu_khz(void) 
537 {
538     INFO("cpu_khz is %u\n", cpu_khz);
539
540     if (cpu_khz == 0) { 
541         INFO("faking cpu_khz to 1000000\n");
542         return 1000000;
543     } else {
544         return cpu_khz;
545     }
546   //return 1000000;
547 }
548
549 /**
550  * Yield the CPU so other host OS tasks can run.
551  * This will return immediately if there is no other thread that is runnable
552  * And there is no real bound on how long it will yield
553  */
554 void
555 palacios_yield_cpu(void)
556 {
557     schedule();
558     return;
559 }
560
561 /**
562  * Yield the CPU so other host OS tasks can run.
563  * Given now immediately if there is no other thread that is runnable
564  * And there is no real bound on how long it will yield
565  */
566 void palacios_yield_cpu_timed(unsigned int us)
567 {
568
569     unsigned int uspj = 1000000U/HZ;
570    
571     unsigned int jiffies = us/uspj + ((us%uspj) !=0);  // ceiling 
572
573     set_current_state(TASK_INTERRUPTIBLE);
574     
575     schedule_timeout(jiffies);
576
577 }
578
579
580 /**
581  * Allocates a mutex.
582  * Returns NULL on failure.
583  */
584 void *
585 palacios_mutex_alloc(void)
586 {
587     spinlock_t *lock = palacios_alloc(sizeof(spinlock_t));
588
589     if (lock) {
590         spin_lock_init(lock);
591     } else {
592         ERROR("ALERT ALERT Unable to allocate lock\n");
593         return NULL;
594     }
595     
596     return lock;
597 }
598
599 /**
600  * Frees a mutex.
601  */
602 void
603 palacios_mutex_free(void * mutex) {
604     palacios_free(mutex);
605 }
606
607 /**
608  * Locks a mutex.
609  */
610 void 
611 palacios_mutex_lock(void * mutex, int must_spin) {
612     spin_lock((spinlock_t *)mutex);
613 }
614
615
616 /**
617  * Locks a mutex, disabling interrupts on this core
618  */
619 void *
620 palacios_mutex_lock_irqsave(void * mutex, int must_spin) {
621     
622     unsigned long flags; 
623     
624     spin_lock_irqsave((spinlock_t *)mutex,flags);
625
626     return (void *)flags;
627 }
628
629
630 /**
631  * Unlocks a mutex.
632  */
633 void 
634 palacios_mutex_unlock(
635         void *                  mutex
636
637 {
638     spin_unlock((spinlock_t *)mutex);
639 }
640
641
642 /**
643  * Unlocks a mutex and restores previous interrupt state on this core
644  */
645 void 
646 palacios_mutex_unlock_irqrestore(void *mutex, void *flags)
647 {
648     // This is correct, flags is opaque
649     spin_unlock_irqrestore((spinlock_t *)mutex,(unsigned long)flags);
650 }
651
652 /**
653  * Structure used by the Palacios hypervisor to interface with the host kernel.
654  */
655 static struct v3_os_hooks palacios_os_hooks = {
656         .print                  = palacios_print,
657         .allocate_pages         = palacios_allocate_pages,
658         .free_pages             = palacios_free_pages,
659         .malloc                 = palacios_alloc,
660         .free                   = palacios_free,
661         .vaddr_to_paddr         = palacios_vaddr_to_paddr,
662         .paddr_to_vaddr         = palacios_paddr_to_vaddr,
663         .hook_interrupt         = palacios_hook_interrupt,
664         .ack_irq                = palacios_ack_interrupt,
665         .get_cpu_khz            = palacios_get_cpu_khz,
666         .start_kernel_thread    = palacios_start_kernel_thread,
667         .yield_cpu              = palacios_yield_cpu,
668         .yield_cpu_timed        = palacios_yield_cpu_timed,
669         .mutex_alloc            = palacios_mutex_alloc,
670         .mutex_free             = palacios_mutex_free,
671         .mutex_lock             = palacios_mutex_lock, 
672         .mutex_unlock           = palacios_mutex_unlock,
673         .mutex_lock_irqsave     = palacios_mutex_lock_irqsave, 
674         .mutex_unlock_irqrestore= palacios_mutex_unlock_irqrestore,
675         .get_cpu                = palacios_get_cpu,
676         .interrupt_cpu          = palacios_interrupt_cpu,
677         .call_on_cpu            = palacios_xcall,
678         .start_thread_on_cpu    = palacios_start_thread_on_cpu,
679         .move_thread_to_cpu     = palacios_move_thread_to_cpu,
680 };
681
682
683
684
685 int palacios_vmm_init( void )
686 {
687     int num_cpus = num_online_cpus();
688     char * cpu_mask = NULL;
689
690     if (cpu_list_len > 0) {
691         int major = 0;
692         int minor = 0;
693         int i = 0;
694
695         cpu_mask = palacios_alloc((num_cpus / 8) + 1);
696
697         if (!cpu_mask) { 
698             ERROR("Cannot allocate cpu mask\n");
699             return -1;
700         }
701
702         memset(cpu_mask, 0, (num_cpus / 8) + 1);
703         
704         for (i = 0; i < cpu_list_len; i++) {
705             if (cpu_list[i] >= num_cpus) {
706                 WARNING("CPU (%d) exceeds number of available CPUs. Ignoring...\n", cpu_list[i]);
707                 continue;
708             }
709
710             major = cpu_list[i] / 8;
711             minor = cpu_list[i] % 8;
712     
713             *(cpu_mask + major) |= (0x1 << minor);
714         }
715     }
716
717     memset(irq_to_guest_map, 0, sizeof(struct v3_vm_info *) * 256);
718
719     if (init_print_buffers()) {
720         ERROR("Cannot initialize print buffers\n");
721         palacios_free(cpu_mask);
722         return -1;
723     }
724
725     INFO("palacios_init starting - calling init_v3\n");
726
727     Init_V3(&palacios_os_hooks, cpu_mask, num_cpus);
728
729     return 0;
730
731 }
732
733
734 int palacios_vmm_exit( void ) {
735
736     Shutdown_V3();
737
738     INFO("palacios shutdown complete\n");
739
740     deinit_print_buffers();
741
742     return 0;
743 }