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.


Improve panic message if asked to free a bad page
[palacios.git] / kitten / palacios-glue / vmm_stubs.c
index 3d44102..aa5f54a 100644 (file)
  * redistribute, and modify it as specified in the file "V3VEE_LICENSE".
  */
 
-#include <palacios/vmm.h>
-#include <palacios/vmm_host_events.h>
-
+#include <lwk/palacios.h>
+#include <lwk/types.h>
 #include <lwk/pmem.h>
+#include <lwk/string.h>
+#include <lwk/cpuinfo.h>
+#include <lwk/kernel.h>
+#include <arch/page.h>
+#include <arch/ptrace.h>
+#include <arch/apic.h>
 
 struct guest_info * g_vm_guest = NULL;
-
-
-// This is the function the interface code should call to deliver
-// the interrupt to the vmm for handling
-//extern int v3_deliver_interrupt(struct guest_info * vm, struct v3_interrupt *intr);
-
-
 struct guest_info * irq_to_guest_map[256];
 
 
 
-
-
-void Init_Stubs(struct guest_info * info) {
-  memset(irq_to_guest_map, 0, sizeof(struct guest_info *) * 256);
-  g_vm_guest = info;
+void
+v3vee_init_stubs( void )
+{
+       memset(irq_to_guest_map, 0, sizeof(irq_to_guest_map) );
 }
 
 
-void * kitten_pa_to_va(void *ptr)
+static void *
+kitten_pa_to_va(void *ptr)
 {
-  return __va(ptr);
+       return (void*) __va(ptr);
 }
 
-void * kitten_va_to_pa(void *ptr)
+
+static void *
+kitten_va_to_pa(
+       void *                  ptr
+)
 {
-  return __pa(ptr);
+       return (void*) __pa(ptr);
 }
 
-void * Allocate_VMM_Pages(int num_pages) 
+
+static void *
+Allocate_VMM_Pages(
+       int                     num_pages
+) 
 {
-  int rc;
-  struct pmem_region result;
+       struct pmem_region result;
   
-  rc=pmem_alloc_umem(num_pages*PAGE_SIZE,PAGE_SIZE,&result);
-  
-  if (rc) {
-    return 0;
-  } else {
-    return result.start;
-  }
+       int rc = pmem_alloc_umem( num_pages*PAGE_SIZE,PAGE_SIZE, &result );
+       if( rc )
+               return 0;
+
+       return (void*) result.start;
 }
 
-void Free_VMM_Page(void * page) 
+static void
+Free_VMM_Page(
+       void *                  page
+) 
 {
-  int rc;
-  struct pmem_region query;
-  struct pmem_region result;
+       struct pmem_region      query;
+       struct pmem_region      result;
 
-  pmem_region_unset_all(&query);
+       pmem_region_unset_all(&query);
 
-  query.start=page;
-  query.end=page+PAGE_SIZE;
+       query.start     = (uintptr_t)( page );
+       query.end       = (uintptr_t)( page + PAGE_SIZE );
 
-  rc=pmem_query(&query,&result);
+       int rc = pmem_query(&query,&result);
 
-  if (!rc) { 
-    result.allocated=FALSE;
-    pmem_update(&result);
-  } else {
-    // BAD
-  }
+       if( rc )
+       {
+               panic( "Asked to free non-allocated page %p! rc=%d",
+                       page,
+                       rc
+               );
+               return;
+       }
+
+       result.allocated = 0;
+       pmem_update(&result);
 }
 
 
-void * VMM_Malloc(unsigned int size) {
-  return Malloc((unsigned long) size);
-}
 
+void
+send_key_to_vmm(
+       unsigned char           status,
+       unsigned char           scancode
+)
+{
+       if( !g_vm_guest )
+               return;
+
+       struct v3_keyboard_event evt = {
+               .status         = status,
+               .scan_code      = scancode,
+       };
 
-void VMM_Free(void * addr) {
-  Free(addr);
+       v3_deliver_keyboard_event( g_vm_guest, &evt );
 }
 
 
+void
+send_mouse_to_vmm(
+       unsigned char           packet[3]
+)
+{
+       if( !g_vm_guest )
+               return;
 
-void send_key_to_vmm(unsigned char status, unsigned char scancode) {
-  struct v3_keyboard_event evt;
-
-  evt.status = status;
-  evt.scan_code = scancode;
+       struct v3_mouse_event evt;
+       memcpy(evt.data, packet, 3);
 
-  if (g_vm_guest) {
-    v3_deliver_keyboard_event(g_vm_guest, &evt);
-  }
+       v3_deliver_mouse_event(g_vm_guest, &evt);
 }
 
 
-void send_mouse_to_vmm(unsigned char packet[3]) {
-  struct v3_mouse_event evt;
+void
+send_tick_to_vmm(
+       unsigned int            period_us
+)
+{
+       if( !g_vm_guest )
+               return;
 
-  memcpy(evt.data, packet, 3);
+       struct v3_timer_event evt = {
+               .period_us      = period_us,
+       };
 
-  if (g_vm_guest) {
-    v3_deliver_mouse_event(g_vm_guest, &evt);
-  }
+       v3_deliver_timer_event( g_vm_guest, &evt );
 }
 
-void send_tick_to_vmm(unsigned int period_us) {
-  struct v3_timer_event evt;
 
-  evt.period_us = period_us;
-
-  if (g_vm_guest) {
-    v3_deliver_timer_event(g_vm_guest, &evt);
-  }
+void
+translate_intr_handler(
+       struct pt_regs *        regs,
+       unsigned int            vector
+) 
+{
+       struct v3_interrupt intr = {
+               .irq            = vector-32,
+               .error          = regs->orig_rax,
+               .should_ack     = 0,
+       };
+
+       //  PrintBoth("translate_intr_handler: opaque=0x%x\n",mystate.opaque);
+       printk( "%s: irq %d\n", __func__, vector );
+       v3_deliver_irq( irq_to_guest_map[intr.irq], &intr );
 }
 
 
-void translate_intr_handler(struct pt_regs *regs, unsigned int vector) 
+int
+kitten_hook_interrupt(
+       struct guest_info *     vm,
+       unsigned int            irq
+)
 {
-  struct v3_interrupt intr;
+       if( irq_to_guest_map[irq] ) {
+               //PrintBoth("Attempt to hook interrupt that is already hooked\n");
+               return -1;
+       }
 
-  intr.irq = vector-32;
-  intr.error = regs->orig_rax;
-  intr.should_ack = 0;
+       //PrintBoth("Hooked interrupt 0x%x with opaque 0x%x\n", irq, vm);
+       printk( "%s: hook irq %d to %p\n", __func__, irq, vm );
+       irq_to_guest_map[irq] = vm;
 
-  //  PrintBoth("translate_intr_handler: opaque=0x%x\n",mystate.opaque);
+       set_idtvec_handler( irq, translate_intr_handler );
+       return 0;
+}
 
-  v3_deliver_irq(irq_to_guest_map[intr.irq], &intr);
 
+static int
+ack_irq(
+       int                     irq
+) 
+{
+       lapic_ack_interrupt();
+       return 0;
 }
 
+  
+static unsigned int
+get_cpu_khz( void ) 
+{
+       return cpu_info[0].arch.cur_cpu_khz;
+}
 
-
-int kitten_hook_interrupt(struct guest_info * vm, unsigned int  irq)
+static void *
+v3vee_alloc(
+       unsigned int size
+)
 {
-  if (irq_to_guest_map[irq]) { 
-    //PrintBoth("Attempt to hook interrupt that is already hooked\n");
-    return -1;
-  } else {
-    //PrintBoth("Hooked interrupt 0x%x with opaque 0x%x\n", irq, vm);
-    irq_to_guest_map[irq] = vm;
-  }
-
-  set_idtvec_handler(irq,translate_intr_handler);
-  return 0;
+       return kmem_alloc( size );
 }
 
 
-int ack_irq(int irq) 
+static void
+v3vee_free(
+       void * addr
+)
 {
-  lapic_ack_interrupt();
-  return 0;
+       return kmem_free( addr );
 }
 
-  
-
 
-unsigned int get_cpu_khz() 
+static void
+v3vee_printk(
+       const char *            fmt,
+       ...
+)
 {
-  return   cpu_info[0].arch.cur_cpu_khz;
+       va_list ap;
+       va_start( ap, fmt );
+       vprintk( fmt, ap );
+       va_end( ap );
 }
 
 
+struct v3_os_hooks v3vee_os_hooks = {
+       .print_debug            = v3vee_printk,  // serial print ideally
+       .print_info             = v3vee_printk,   // serial print ideally
+       .print_trace            = v3vee_printk,  // serial print ideally
+       .allocate_pages         = Allocate_VMM_Pages, // defined in vmm_stubs
+       .free_page              = Free_VMM_Page, // defined in vmm_stubs
+       .malloc                 = v3vee_alloc,
+       .free                   = v3vee_free,
+       .vaddr_to_paddr         = kitten_va_to_pa,
+       .paddr_to_vaddr         = kitten_pa_to_va,
+       .hook_interrupt         = kitten_hook_interrupt,
+       .ack_irq                = ack_irq,
+       .get_cpu_khz            = get_cpu_khz,
+};
+