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.


*** empty log message ***
Jack Lange [Fri, 29 Feb 2008 19:25:24 +0000 (19:25 +0000)]
palacios/build/Makefile
palacios/include/geekos/svm.h
palacios/include/geekos/vmcb.h
palacios/include/geekos/vmm.h
palacios/include/geekos/vmm_stubs.h [new file with mode: 0644]
palacios/include/geekos/vmm_util.h
palacios/src/geekos/main.c
palacios/src/geekos/svm.c
palacios/src/geekos/vmm_stubs.c [new file with mode: 0644]
palacios/src/geekos/vmx.c

index 9401105..7587e29 100644 (file)
@@ -1,6 +1,6 @@
 # Makefile for GeekOS kernel, userspace, and tools
 # Copyright (c) 2004,2005 David H. Hovemeyer <daveho@cs.umd.edu>
-# $Revision: 1.11 $
+# $Revision: 1.12 $
 
 # This is free software.  You are permitted to use,
 # redistribute, and modify it as specified in the file "COPYING".
@@ -97,8 +97,8 @@ KERNEL_C_SRCS := idt.c int.c trap.c irq.c io.c \
        bget.c malloc.c \
        synch.c kthread.c \
        serial.c  reboot.c \
-        paging.c vmx.c vmcs_gen.c vmcs.c\
-        svm.c vmm.c vmm_util.c \
+        paging.c vmx.c vmcs_gen.c vmcs.c \
+        svm.c vmm.c vmm_util.c vmm_stubs.c \
        debug.c\
        main.c
 
index fccddc2..bb967f3 100644 (file)
@@ -1,6 +1,7 @@
 #ifndef __SVM_H
 #define __SVM_H
 
+#include <geekos/vmm_util.h>
 #include <geekos/vmm.h>
 
 #define CPUID_FEATURE_IDS 0x80000001
@@ -38,6 +39,7 @@
 #define SVM_SMM_CTL_MSR_rsm_cycle 0x00000010
 
 #define SVM_VM_HSAVE_PA_MSR      0xc0010117
+
 #define SVM_KEY_MSR              0xc0010118
 
 /******/
index 212daaf..e6d609f 100644 (file)
@@ -3,6 +3,13 @@
 
 
 
+#define VMCB_CTRL_AREA_OFFSET                   0x0
+#define VMCB_STATE_SAVE_AREA_OFFSET             0x400
+
+
+#define GET_VMCB_CTRL_AREA(page)         (page + VMCB_CONTROL_AREA_OFFSET)
+#define GET_VMCB_SAVE_STATE_AREA(page)   (page + VMCB_STATE_SAVE_AREA_OFFSET)
+
 
 #if __TINYC__
 #define PACKED
@@ -57,7 +64,7 @@ union Debug_Registers {
 
 
 union Exception_Vectors {
-  ulong_t bitmap                  PACKED;
+  uint_t bitmap                  PACKED;
   struct {
     uint_t ex0         : 1        PACKED;
     uint_t ex1         : 1        PACKED;
@@ -96,7 +103,7 @@ union Exception_Vectors {
 
 
 union Instr_Intercepts {
-  ulong_t bitmap                  PACKED;
+  uint_t bitmap                  PACKED;
   struct {
     uint_t INTR        : 1        PACKED;
     uint_t NMI         : 1        PACKED;
@@ -134,7 +141,7 @@ union Instr_Intercepts {
 };
 
 union SVM_Instr_Intercepts { 
-  ulong_t bitmap                  PACKED;
+  uint_t bitmap                  PACKED;
   struct {
     uint_t VMRUN      : 1         PACKED;
     uint_t VMMCALL    : 1         PACKED;
@@ -149,24 +156,24 @@ union SVM_Instr_Intercepts {
     uint_t MONITOR    : 1         PACKED;
     uint_t MWAIT_always : 1       PACKED;
     uint_t MWAIT_if_armed : 1     PACKED;
-    ulong_t reserved  : 19        PACKED;
+    uint_t reserved  : 19         PACKED;  // Should be 0
   } instrs;
 };
 
 
 union Guest_Control {
-  ulong_t bitmap                  PACKED;
+  uint_t bitmap                  PACKED;
   struct {
     uchar_t V_TPR                 PACKED;
     uint_t V_IRQ      : 1         PACKED;
-    uint_t rsvd1      : 7         PACKED;
+    uint_t rsvd1      : 7         PACKED;  // Should be 0
     uint_t V_INTR_PRIO : 4        PACKED;
     uint_t V_IGN_TPR  : 1         PACKED;
-    uint_t rsvd2      : 3         PACKED;
+    uint_t rsvd2      : 3         PACKED;  // Should be 0
     uint_t V_INTR_MASKING : 1     PACKED;
-    uint_t rsvd3      : 7         PACKED;
+    uint_t rsvd3      : 7         PACKED;  // Should be 0
     uchar_t V_INTR_VECTOR         PACKED;
-    uint_t rsvd4      : 24        PACKED;
+    uint_t rsvd4      : 24        PACKED;  // Should be 0
   } ctrls;
 };
 
@@ -174,52 +181,52 @@ union Guest_Control {
 
 typedef struct VMCB_Control_Area {
   // offset 0x0
-  union Ctrl_Registers cr_reads        PACKED;
-  union Ctrl_Registers cr_writes       PACKED;
-  union Debug_Registers dr_reads       PACKED;
-  union Debug_Registers dr_writes      PACKED;
-  union Exception_Vectors exceptions   PACKED;
-  union Instr_Intercepts instrs        PACKED;
+  union Ctrl_Registers cr_reads         PACKED;
+  union Ctrl_Registers cr_writes        PACKED;
+  union Debug_Registers dr_reads        PACKED;
+  union Debug_Registers dr_writes       PACKED;
+  union Exception_Vectors exceptions    PACKED;
+  union Instr_Intercepts instrs         PACKED;
   union SVM_Instr_Intercepts svm_instrs PACKED;
 
-  uchar_t rsvd1[43]                    PACKED;
+  uchar_t rsvd1[43]                     PACKED;  // Should be 0
 
   // offset 0x040
-  ullong_t IOPM_BASE_PA                PACKED;
-  ullong_t MSRPM_BASE_PA               PACKED;
-  ullong_t TSC_OFFSET                  PACKED;
+  ullong_t IOPM_BASE_PA                 PACKED;
+  ullong_t MSRPM_BASE_PA                PACKED;
+  ullong_t TSC_OFFSET                   PACKED;
 
-  ulong_t guest_ASID                   PACKED;
-  uchar_t TLB_CONTROL                  PACKED;
+  uint_t guest_ASID                     PACKED;
+  uchar_t TLB_CONTROL                   PACKED;
 
-  uchar_t rsvd2[3]                     PACKED;
+  uchar_t rsvd2[3]                      PACKED;  // Should be 0
 
-  union Guest_Control guest_ctrl       PACKED;
+  union Guest_Control guest_ctrl        PACKED;
   
-  ulong_t interrupt_shadow  : 1        PACKED;
-  ulong_t rsvd3             : 31       PACKED;
-  ulong_t rsvd4                        PACKED;
+  uint_t interrupt_shadow  : 1          PACKED;
+  uint_t rsvd3             : 31         PACKED;  // Should be 0
+  uint_t rsvd4                          PACKED;  // Should be 0
 
-  ullong_t exit_code                   PACKED;
-  ullong_t exit_info1                  PACKED;
-  ullong_t exit_info2                  PACKED;
+  ullong_t exit_code                    PACKED;
+  ullong_t exit_info1                   PACKED;
+  ullong_t exit_info2                   PACKED;
 
   /* This could be a typo in the manual....
    * It doesn't actually say that there is a reserved bit
    * But it does say that the EXITINTINFO field is in bits 63-1
    * ALL other occurances mention a 1 bit reserved field
    */
-  ulong_t rsvd5             : 1        PACKED;
-  ullong_t exit_int_info    : 63       PACKED;
+  uint_t rsvd5             : 1          PACKED;
+  ullong_t exit_int_info   : 63         PACKED;
   /* ** */
 
-  ulong_t NP_ENABLE         : 1        PACKED;
-  ullong_t rsvd6            : 63       PACKED;
+  uint_t NP_ENABLE         : 1          PACKED;
+  ullong_t rsvd6           : 63         PACKED;  // Should be 0 
 
-  uchar_t rsvd7[15]                    PACKED;
+  uchar_t rsvd7[15]                     PACKED;  // Should be 0
 
   // Offset 0xA8
-  ullong_t EVENTINJ                    PACKED;
+  ullong_t EVENTINJ                     PACKED;
 
 
   /* This could be a typo in the manual....
@@ -227,12 +234,12 @@ typedef struct VMCB_Control_Area {
    * But it does say that the EXITINTINFO field is in bits 63-1
    * ALL other occurances mention a 1 bit reserved field
    */
-  ulong_t rsvd8             : 1        PACKED;
-  ullong_t N_CR3            : 63       PACKED;
+  uint_t rsvd8              : 1         PACKED;
+  ullong_t N_CR3            : 63        PACKED;
   /* ** */
 
-  ulong_t LBR_VIRTUALIZATION_ENABLE  : 1  PACKED;
-  ullong_t rsvd9            : 63       PACKED;
+  uint_t LBR_VIRTUALIZATION_ENABLE : 1  PACKED;
+  ullong_t rsvd9            : 63        PACKED;   // Should be 0
 
 } vmcb_ctrl_t;
 
@@ -244,16 +251,11 @@ typedef struct VMCB_Control_Area {
 struct vmcb_selector {
   ushort_t selector                   PACKED;
   ushort_t attrib                     PACKED;
-  ulong_t  limit                      PACKED;
+  uint_t  limit                       PACKED;
   ullong_t base                       PACKED;
 }
 
 
-
-
-
-
-
 typedef struct VMCB_State_Save_Area {
   struct vmcb_selector es            PACKED; // only lower 32 bits of base are implemented
   struct vmcb_selector cs            PACKED; // only lower 32 bits of base are implemented
@@ -273,7 +275,7 @@ typedef struct VMCB_State_Save_Area {
   uchar_t cpl                        PACKED; // if the guest is real-mode then the CPL is forced to 0
                                              // if the guest is virtual-mode then the CPL is forced to 3
 
-  ulong_t rsvd2                      PACKED;
+  uint_t rsvd2                       PACKED;
 
   // offset 0x0d0
   ullong_t efer                      PACKED;
@@ -312,12 +314,18 @@ typedef struct VMCB_State_Save_Area {
   uchar_t rsvd6[31]                  PACKED;
 
   //offset 0x268
-  ullong_t g_pat                     PACKED; // Guest PAT                          -- only used if nested paging is enabled
-  ullong_t dbgctl                    PACKED; // Guest DBGCTL MSR                   -- only used if the LBR registers are virtualized
-  ullong_t br_from                   PACKED; // Guest LastBranchFromIP MSR         -- only used if the LBR registers are virtualized
-  ullong_t br_to                     PACKED; // Guest LastBranchToIP MSR           -- only used if the LBR registers are virtualized
-  ullong_t lastexcpfrom              PACKED; // Guest LastExceptionFromIP MSR      -- only used if the LBR registers are virtualized
-  ullong_t lastexcpto                PACKED; // Guest LastExceptionToIP MSR        -- only used if the LBR registers are virtualized
+  ullong_t g_pat                     PACKED; // Guest PAT                     
+                                             //   -- only used if nested paging is enabled
+  ullong_t dbgctl                    PACKED; // Guest DBGCTL MSR               
+                                             //   -- only used if the LBR registers are virtualized
+  ullong_t br_from                   PACKED; // Guest LastBranchFromIP MSR
+                                             //   -- only used if the LBR registers are virtualized
+  ullong_t br_to                     PACKED; // Guest LastBranchToIP MSR   
+                                             //   -- only used if the LBR registers are virtualized
+  ullong_t lastexcpfrom              PACKED; // Guest LastExceptionFromIP MSR
+                                             //   -- only used if the LBR registers are virtualized
+  ullong_t lastexcpto                PACKED; // Guest LastExceptionToIP MSR 
+                                             //   -- only used if the LBR registers are virtualized
 
 } vmcb_saved_state_t;
 
index 467fe24..89b56f1 100644 (file)
@@ -40,7 +40,6 @@
 
 
 
-
 #define VMM_INVALID_CPU 0
 #define VMM_VMX_CPU 1
 #define VMM_SVM_CPU 2
@@ -51,6 +50,9 @@ struct vmm_os_hooks {
   void (*print_info)(const char * format, ...);
   void (*print_debug)(const char * format, ...);
   void (*print_trace)(const char * format, ...);
+  
+  void *(*Allocate_Pages)(int numPages);
+  void (*Free_Page)(void * page); 
 };
 
 
diff --git a/palacios/include/geekos/vmm_stubs.h b/palacios/include/geekos/vmm_stubs.h
new file mode 100644 (file)
index 0000000..b964280
--- /dev/null
@@ -0,0 +1,14 @@
+#ifndef __VMM_STUBS_H
+#define __VMM_STUBS_H
+
+
+#include <geekos/mem.h>
+
+
+void * Allocate_VMM_Pages(int num_pages);
+void Free_VMM_Page(void * page);
+
+
+
+
+#endif
index 144d886..5fb0aea 100644 (file)
@@ -5,6 +5,19 @@
 
 
 
+//#define PAGE_SIZE 4096
+
+typedef union reg_ex {
+  ullong_t r_reg;
+  struct {
+    uint_t low;
+    uint_t high;
+  } e_reg;
+
+} reg_ex_t;
+
+
+
 void PrintTraceHex(unsigned char x);
 
 void PrintTraceMemDump(unsigned char * start, int n);
index 41ece4d..e09ef5c 100644 (file)
@@ -3,7 +3,7 @@
  * Copyright (c) 2001,2003,2004 David H. Hovemeyer <daveho@cs.umd.edu>
  * Copyright (c) 2003, Jeffrey K. Hollingsworth <hollings@cs.umd.edu>
  * Copyright (c) 2004, Iulian Neamtiu <neamtiu@cs.umd.edu>
- * $Revision: 1.11 $
+ * $Revision: 1.12 $
  * 
  * This is free software.  You are permitted to use,
  * redistribute, and modify it as specified in the file "COPYING".
@@ -33,6 +33,7 @@
 #include <geekos/gdt.h>
 
 #include <geekos/vmm_sizes.h>
+#include <geekos/vmm_stubs.h>
 
 /*
   static inline unsigned int cpuid_ecx(unsigned int op)
@@ -147,9 +148,6 @@ void RunVM() {
 
 
 
-extern uint_t VMCS_STORE();
-extern uint_t VMCS_READ();
-
 
 
 void Buzzer(ulong_t arg) {
@@ -166,6 +164,8 @@ void Buzzer(ulong_t arg) {
 
 
 
+
+
 void Hello(ulong_t arg)
 {
   char *b="hello ";
@@ -247,6 +247,8 @@ void VM_Thread(ulong_t arg)
 }
 */
 
+
+
 int AllocateAndMapPagesForRange(uint_t start, uint_t length, pte_t template_pte)
 {
   uint_t address;
@@ -325,6 +327,8 @@ void Main(struct Boot_Info* bootInfo)
   os_hooks.print_debug = &PrintBoth;
   os_hooks.print_info = &Print;
   os_hooks.print_trace = &SerialPrint;
+  os_hooks.Allocate_Pages = &Allocate_VMM_Pages;
+  os_hooks.Free_Page = &Free_VMM_Page;
 
   Init_VMM(&os_hooks);
 
index fcf5a00..88ab002 100644 (file)
@@ -1,16 +1,18 @@
 #include <geekos/svm.h>
 
 
+extern struct vmm_os_hooks * os_hooks;
+
 extern uint_t cpuid_ecx(uint_t op);
 extern uint_t cpuid_edx(uint_t op);
-extern void Get_MSR(uint_t MSR, ulong_t * high_byte, ulong_t * low_byte); 
-extern void Set_MSR(uint_t MSR, ulong_t high_byte, ulong_t low_byte);
+extern void Get_MSR(uint_t MSR, uint_t * high_byte, uint_t * low_byte); 
+extern void Set_MSR(uint_t MSR, uint_t high_byte, uint_t low_byte);
 
 /* Checks machine SVM capability */
 /* Implemented from: AMD Arch Manual 3, sect 15.4 */ 
 int is_svm_capable() {
   uint_t ret =  cpuid_ecx(CPUID_FEATURE_IDS);
-  ulong_t vm_cr_low = 0, vm_cr_high = 0;
+  uint_t vm_cr_low = 0, vm_cr_high = 0;
 
 
   if ((ret & CPUID_FEATURE_IDS_ecx_svm_avail) == 0) {
@@ -35,14 +37,39 @@ int is_svm_capable() {
   return 0;
 }
 
+
+
 void Init_SVM() {
-  ulong_t msr_val_low = 0, msr_val_high = 0;
+  reg_ex_t msr;
+  void * host_state;
+
 
-  Get_MSR(EFER_MSR, &msr_val_high, &msr_val_low);
-  msr_val_low |= EFER_MSR_svm_enable;
-  Set_MSR(EFER_MSR, 0, msr_val_low);
+  // setup 
+  Get_MSR(EFER_MSR, &(msr.e_reg.high), &(msr.e_reg.low));
+  msr.e_reg.low |= EFER_MSR_svm_enable;
+  Set_MSR(EFER_MSR, 0, msr.e_reg.low);
   
-  PrintDebug("SVM Inited\n");
+  PrintDebug("SVM Enabled\n");
+
+
+  // Setup the host state save area
+  host_state = os_hooks->Allocate_Pages(1);
+  
+  msr.e_reg.high = 0;
+  msr.e_reg.low = (uint_t)host_state;
+
+  Set_MSR(SVM_VM_HSAVE_PA_MSR, msr.e_reg.high, msr.e_reg.low);
+
 
   return;
 }
+
+
+
+
+void Allocate_VMCB() {
+  void * vmcb_page = os_hooks->Allocate_Pages(1);
+
+
+  memset(vmcb_page, 0, 4096);
+}
diff --git a/palacios/src/geekos/vmm_stubs.c b/palacios/src/geekos/vmm_stubs.c
new file mode 100644 (file)
index 0000000..51f5801
--- /dev/null
@@ -0,0 +1,14 @@
+#include <geekos/vmm_stubs.h>
+
+
+
+void * Allocate_VMM_Pages(int num_pages) {
+  return Alloc_Page();
+}
+
+
+
+
+void Free_VMM_Page(void * page) {
+  Free_Page(page);
+}
index 84b6bd6..8aa8b2f 100644 (file)
@@ -186,7 +186,7 @@ void SetCtrlBitsCorrectly(int msrno, int vmcsno)
   uint_t reserved =0;
   union VMX_MSR msr;
 
-  PrintTrace("SetCtrlBitsCorrectly(%x,%x)\n",msrno,vmcsno);
+  PrintTrace("SetCtrlBitsCorrectly(%x,%x)\n", msrno, vmcsno);
   Get_MSR(msrno, &msr.regs.high, &msr.regs.low);
   PrintTrace("MSR %x = %x : %x \n", msrno, msr.regs.high, msr.regs.low);
   reserved = msr.regs.low;
@@ -216,8 +216,8 @@ extern int vmRunning;
 
 static int PanicUnhandledVMExit(struct VM *vm)
 {
-  Print("Panicking due to VMExit with reason %u\n",vm->vmcs.exitInfoFields.reason);
-  PrintTrace("Panicking due to VMExit with reason %u\n",vm->vmcs.exitInfoFields.reason);
+  PrintInfo("Panicking due to VMExit with reason %u\n", vm->vmcs.exitInfoFields.reason);
+  PrintTrace("Panicking due to VMExit with reason %u\n", vm->vmcs.exitInfoFields.reason);
   PrintTrace_VMCS_ALL();
   PrintTrace_VMX_Regs(&(vm->registers));
   VMXPanic();
@@ -267,13 +267,13 @@ static int HandleInOutExit(struct VM *vm)
   address=GetLinearIP(vm);
 
   PrintTrace("Handling Input/Output Instruction Exit\n");
-  if (SERIAL_PRINT_DEBUG && 1000>=SERIAL_PRINT_DEBUG_LEVEL) {
-      PrintTrace_VMX_Regs(regs);
-  }
-  PrintTrace("Qualifications=0x%x\n",exitinfo->qualification);
-  PrintTrace("Reason=0x%x\n",exitinfo->reason);
+
+  PrintTrace_VMX_Regs(regs);
+
+  PrintTrace("Qualifications=0x%x\n", exitinfo->qualification);
+  PrintTrace("Reason=0x%x\n", exitinfo->reason);
   PrintTrace("IO Port: 0x%x (%d)\n", qual->port, qual->port);
-  PrintTrace("Instruction Info=%x\n",exitinfo->instrInfo);
+  PrintTrace("Instruction Info=%x\n", exitinfo->instrInfo);
   PrintTrace("%x : %s %s %s instruction of length %d for %d bytes from/to port 0x%x\n",
                   address,
                   qual->dir == 0 ? "output" : "input",
@@ -283,20 +283,20 @@ static int HandleInOutExit(struct VM *vm)
                   qual->accessSize==0 ? 1 : qual->accessSize==1 ? 2 : 4,
                   qual->port);
 
-  if (qual->port==PIC_MASTER_CMD_ISR_PORT ||
-      qual->port==PIC_MASTER_IMR_PORT ||
-      qual->port==PIC_SLAVE_CMD_ISR_PORT ||
-      qual->port==PIC_SLAVE_IMR_PORT) {
+  if ((qual->port == PIC_MASTER_CMD_ISR_PORT) ||
+      (qual->port == PIC_MASTER_IMR_PORT)     ||
+      (qual->port == PIC_SLAVE_CMD_ISR_PORT)  ||
+      (qual->port == PIC_SLAVE_IMR_PORT)) {
     PrintTrace( "PIC Access\n");
   }
                   
 
-  if (qual->dir==1 && qual->REP==0 && qual->string==0) { 
+  if ((qual->dir == 1) && (qual->REP == 0) && (qual->string == 0)) { 
     char byte = In_Byte(qual->port);
 
     vm->vmcs.guestStateArea.rip += exitinfo->instrLength;
     regs->eax = (regs->eax & 0xffffff00) | byte;
-    PrintTrace("Returning 0x%x in eax\n",(regs->eax));
+    PrintTrace("Returning 0x%x in eax\n", (regs->eax));
   }
 
   if (qual->dir==0 && qual->REP==0 && qual->string==0) { 
@@ -844,7 +844,7 @@ int MyLaunch(struct VM *vm)
   //  tmpReg = 0x4100;
   tmpReg = 0xffffffff;
   if (VMCS_WRITE(EXCEPTION_BITMAP,&tmpReg ) != VMX_SUCCESS) {
-    Print("Bitmap error\n");
+    PrintInfo("Bitmap error\n");
   }
 
   ConfigureExits(vm);
@@ -891,7 +891,7 @@ VmxOnRegion * CreateVmxOnRegion() {
 
   *(ulong_t*)region = basicMSR.vmxBasic.revision;
 
-  Print("VMX revision: 0x%lu\n", *(ulong_t *)region);
+  PrintInfo("VMX revision: 0x%lu\n", *(ulong_t *)region);
 
   return region;
 }