# 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".
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
#ifndef __SVM_H
#define __SVM_H
+#include <geekos/vmm_util.h>
#include <geekos/vmm.h>
#define CPUID_FEATURE_IDS 0x80000001
#define SVM_SMM_CTL_MSR_rsm_cycle 0x00000010
#define SVM_VM_HSAVE_PA_MSR 0xc0010117
+
#define SVM_KEY_MSR 0xc0010118
/******/
+#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
union Exception_Vectors {
- ulong_t bitmap PACKED;
+ uint_t bitmap PACKED;
struct {
uint_t ex0 : 1 PACKED;
uint_t ex1 : 1 PACKED;
union Instr_Intercepts {
- ulong_t bitmap PACKED;
+ uint_t bitmap PACKED;
struct {
uint_t INTR : 1 PACKED;
uint_t NMI : 1 PACKED;
};
union SVM_Instr_Intercepts {
- ulong_t bitmap PACKED;
+ uint_t bitmap PACKED;
struct {
uint_t VMRUN : 1 PACKED;
uint_t VMMCALL : 1 PACKED;
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;
};
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....
* 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;
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
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;
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;
-
#define VMM_INVALID_CPU 0
#define VMM_VMX_CPU 1
#define VMM_SVM_CPU 2
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);
};
--- /dev/null
+#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
+//#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);
* 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".
#include <geekos/gdt.h>
#include <geekos/vmm_sizes.h>
+#include <geekos/vmm_stubs.h>
/*
static inline unsigned int cpuid_ecx(unsigned int op)
-extern uint_t VMCS_STORE();
-extern uint_t VMCS_READ();
-
void Buzzer(ulong_t arg) {
+
+
void Hello(ulong_t arg)
{
char *b="hello ";
}
*/
+
+
int AllocateAndMapPagesForRange(uint_t start, uint_t length, pte_t template_pte)
{
uint_t address;
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);
#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) {
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);
+}
--- /dev/null
+#include <geekos/vmm_stubs.h>
+
+
+
+void * Allocate_VMM_Pages(int num_pages) {
+ return Alloc_Page();
+}
+
+
+
+
+void Free_VMM_Page(void * page) {
+ Free_Page(page);
+}
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;
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();
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",
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) {
// tmpReg = 0x4100;
tmpReg = 0xffffffff;
if (VMCS_WRITE(EXCEPTION_BITMAP,&tmpReg ) != VMX_SUCCESS) {
- Print("Bitmap error\n");
+ PrintInfo("Bitmap error\n");
}
ConfigureExits(vm);
*(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;
}