From: Jack Lange Date: Tue, 11 Mar 2008 06:01:45 +0000 (+0000) Subject: WTF?????? X-Git-Tag: working-cdboot-physical-but-not-qemu~57 X-Git-Url: http://v3vee.org/palacios/gitweb/gitweb.cgi?p=palacios.git;a=commitdiff_plain;h=04fc4c8fbac29e04f0d0817a2906687c2c972559 WTF?????? --- diff --git a/palacios/include/geekos/vmcb.h b/palacios/include/geekos/vmcb.h index ebcce6b..894c12e 100644 --- a/palacios/include/geekos/vmcb.h +++ b/palacios/include/geekos/vmcb.h @@ -259,8 +259,9 @@ typedef struct VMCB_Control_Area { ullong_t exit_int_info : 63 PACKED; /* ** */ - uint_t NP_ENABLE : 1 PACKED; - ullong_t rsvd6 : 63 PACKED; // Should be 0 + // uint_t NP_ENABLE : 1 PACKED; + //ullong_t rsvd6 : 63 PACKED; // Should be 0 + ullong_t NP_ENABLE PACKED; uchar_t rsvd7[16] PACKED; // Should be 0 @@ -387,7 +388,7 @@ typedef struct VMCB_State_Save_Area { } vmcb_saved_state_t; - +void PrintDebugVMCB(vmcb_t * vmcb); #endif diff --git a/palacios/include/geekos/vmm.h b/palacios/include/geekos/vmm.h index 93e7211..181155f 100644 --- a/palacios/include/geekos/vmm.h +++ b/palacios/include/geekos/vmm.h @@ -77,7 +77,7 @@ typedef struct guest_info { vmm_mem_layout_t mem_layout; // device_map - vmm_pde_t * page_tables; + pml4e64_t * page_tables; void * vmm_data; } guest_info_t; diff --git a/palacios/include/geekos/vmm_paging.h b/palacios/include/geekos/vmm_paging.h index b97d835..6125d5d 100644 --- a/palacios/include/geekos/vmm_paging.h +++ b/palacios/include/geekos/vmm_paging.h @@ -11,6 +11,10 @@ #define MAX_PAGE_TABLE_ENTRIES 1024 #define MAX_PAGE_DIR_ENTRIES 1024 +#define MAX_PAGE_TABLE_ENTRIES_64 512 +#define MAX_PAGE_DIR_ENTRIES_64 512 +#define MAX_PAGE_DIR_PTR_ENTRIES_64 512 +#define MAX_PAGE_MAP_ENTRIES_64 512 #define PAGE_DIRECTORY_INDEX(x) ((((uint_t)x) >> 22) & 0x3ff) #define PAGE_TABLE_INDEX(x) ((((uint_t)x) >> 12) & 0x3ff) @@ -54,7 +58,72 @@ typedef struct pte { } vmm_pte_t; + +typedef struct pte64 { + uint_t present : 1; + uint_t flags : 4; + uint_t accessed : 1; + uint_t dirty : 1; + uint_t pte_attr : 1; + uint_t global_page : 1; + uint_t vmm_info : 3; + uint_t page_base_addr_lo : 20; + uint_t page_base_addr_hi : 20; + uint_t available : 11; + uint_t no_execute : 1; +} pte64_t; + +typedef struct pde64 { + uint_t present : 1; + uint_t flags : 4; + uint_t accessed : 1; + uint_t reserved : 1; + uint_t large_pages : 1; + uint_t reserved2 : 1; + uint_t vmm_info : 3; + uint_t pt_base_addr_lo : 20; + uint_t pt_base_addr_hi : 20; + uint_t available : 11; + uint_t no_execute : 1; +} pde64_t; + +typedef struct pdpe64 { + uint_t present : 1; + uint_t writable : 1; + uint_t user : 1; + uint_t pwt : 1; + uint_t pcd : 1; + uint_t accessed : 1; + uint_t reserved : 1; + uint_t large_pages : 1; + uint_t zero : 1; + uint_t vmm_info : 3; + uint_t pd_base_addr_lo : 20; + uint_t pd_base_addr_hi : 20; + uint_t available : 11; + uint_t no_execute : 1; +} pdpe64_t; + + +typedef struct pml4e { + uint_t present : 1; + uint_t writable : 1; + uint_t user : 1; + uint_t pwt : 1; + uint_t pcd : 1; + uint_t accessed : 1; + uint_t reserved : 1; + uint_t zero : 2; + uint_t vmm_info : 3; + uint_t pdp_base_addr_lo : 20; + uint_t pdp_base_addr_hi : 20; + uint_t available : 11; + uint_t no_execute : 1; +} pml4e64_t; + + vmm_pde_t * generate_guest_page_tables(vmm_mem_layout_t * layout, vmm_mem_list_t * list); +pml4e64_t * generate_guest_page_tables_64(vmm_mem_layout_t * layout, vmm_mem_list_t * list); void free_guest_page_tables(vmm_pde_t * pde); diff --git a/palacios/src/geekos/gdt.c b/palacios/src/geekos/gdt.c index 3667d46..d206939 100644 --- a/palacios/src/geekos/gdt.c +++ b/palacios/src/geekos/gdt.c @@ -1,7 +1,7 @@ /* * Initialize kernel GDT. * Copyright (c) 2001,2004 David H. Hovemeyer - * $Revision: 1.2 $ + * $Revision: 1.3 $ * * This is free software. You are permitted to use, * redistribute, and modify it as specified in the file "COPYING". @@ -168,6 +168,8 @@ void Init_GDT(void) ); KASSERT(Get_Descriptor_Index(desc) == (KERNEL_DS >> 3)); + Print("GDT: Base=0x%.8x, limit=%d\n", (uint_t)gdtBaseAddr, (uint_t)(sizeof(struct Segment_Descriptor) * NUM_GDT_ENTRIES)); + /* Activate the kernel GDT. */ limitAndBase[0] = sizeof(struct Segment_Descriptor) * NUM_GDT_ENTRIES; limitAndBase[1] = gdtBaseAddr & 0xffff; diff --git a/palacios/src/geekos/lowlevel.asm b/palacios/src/geekos/lowlevel.asm index 9869d9f..fe3b61b 100644 --- a/palacios/src/geekos/lowlevel.asm +++ b/palacios/src/geekos/lowlevel.asm @@ -2,7 +2,7 @@ ; Low level interrupt/thread handling code for GeekOS. ; Copyright (c) 2001,2003,2004 David H. Hovemeyer ; Copyright (c) 2003, Jeffrey K. Hollingsworth -; $Revision: 1.4 $ +; $Revision: 1.5 $ ; This is free software. You are permitted to use, ; redistribute, and modify it as specified in the file "COPYING". @@ -171,9 +171,11 @@ EXPORT cpuid_edx EXPORT Set_MSR EXPORT Get_MSR + EXPORT Get_CR2 EXPORT Get_CR3 + EXPORT Proc_test ; ---------------------------------------------------------------------- @@ -373,6 +375,7 @@ Get_MSR: + align 8 Get_CR2: mov eax, cr2 diff --git a/palacios/src/geekos/main.c b/palacios/src/geekos/main.c index 5f12931..87bea69 100644 --- a/palacios/src/geekos/main.c +++ b/palacios/src/geekos/main.c @@ -3,7 +3,7 @@ * Copyright (c) 2001,2003,2004 David H. Hovemeyer * Copyright (c) 2003, Jeffrey K. Hollingsworth * Copyright (c) 2004, Iulian Neamtiu - * $Revision: 1.17 $ + * $Revision: 1.18 $ * * This is free software. You are permitted to use, * redistribute, and modify it as specified in the file "COPYING". @@ -262,6 +262,8 @@ void Main(struct Boot_Info* bootInfo) SerialMemDump((unsigned char *)0x100000, 512*2); #endif + key_thread = Start_Kernel_Thread(Keyboard_Listener, (ulong_t)&doIBuzz, PRIORITY_NORMAL, false); + spkr_thread = Start_Kernel_Thread(Buzzer, (ulong_t)&doIBuzz, PRIORITY_NORMAL, false); { @@ -314,8 +316,8 @@ void Main(struct Boot_Info* bootInfo) SerialPrintLevel(1000,"Launching Noisemaker and keyboard listener threads\n"); - key_thread = Start_Kernel_Thread(Keyboard_Listener, (ulong_t)&doIBuzz, PRIORITY_NORMAL, false); - spkr_thread = Start_Kernel_Thread(Buzzer, (ulong_t)&doIBuzz, PRIORITY_NORMAL, false); + + diff --git a/palacios/src/geekos/svm.c b/palacios/src/geekos/svm.c index 75e65f8..6d9d487 100644 --- a/palacios/src/geekos/svm.c +++ b/palacios/src/geekos/svm.c @@ -15,6 +15,10 @@ extern void Set_MSR(uint_t MSR, uint_t high_byte, uint_t low_byte); extern uint_t launch_svm(vmcb_t * vmcb_addr); extern uint_t Get_CR3(); +extern void GetGDTR(void * gdt); +extern void GetIDTR(void * idt); + + /* Checks machine SVM capability */ /* Implemented from: AMD Arch Manual 3, sect 15.4 */ int is_svm_capable() { @@ -94,7 +98,7 @@ int init_svm_guest(struct guest_info *info) { PrintDebug("Generating Guest nested page tables\n"); print_mem_list(&(info->mem_list)); print_mem_layout(&(info->mem_layout)); - info->page_tables = generate_guest_page_tables(&(info->mem_layout), &(info->mem_list)); + info->page_tables = generate_guest_page_tables_64(&(info->mem_layout), &(info->mem_list)); //PrintDebugPageTables(info->page_tables); @@ -116,6 +120,8 @@ int start_svm_guest(struct guest_info *info) { ulong_t exit_code = 0; PrintDebug("Launching SVM VM (vmcb=%x)\n", info->vmm_data); + // PrintDebugVMCB((vmcb_t*)(info->vmm_data)); + launch_svm((vmcb_t*)(info->vmm_data)); @@ -200,6 +206,12 @@ void Init_VMCB(vmcb_t *vmcb, guest_info_t vm_info) { ctrl_area->guest_ASID = 1; + // guest_state->cpl = 3; + + + + + // Setup exits @@ -214,24 +226,58 @@ void Init_VMCB(vmcb_t *vmcb, guest_info_t vm_info) { ctrl_area->exceptions.ex_names.ud = 1; ctrl_area->exceptions.ex_names.np = 1; ctrl_area->exceptions.ex_names.of = 1; + ctrl_area->exceptions.ex_names.nmi = 1; + + + // ctrl_area->instrs.instrs.IOIO_PROT = 1; + ctrl_area->IOPM_BASE_PA = (uint_t)os_hooks->allocate_pages(3); + + { + reg_ex_t tmp_reg; + tmp_reg.r_reg = ctrl_area->IOPM_BASE_PA; + memset((void*)(tmp_reg.e_reg.low), 0xffffffff, PAGE_SIZE * 2); + } + + ctrl_area->instrs.instrs.INTR = 1; + + /* + { + reg_ex_t gdt; + reg_ex_t idt; + + GetGDTR(&(gdt.r_reg)); + PrintDebug("GDT: hi: %x, lo: %x\n", gdt.e_reg.high, gdt.e_reg.low); + + GetIDTR(&(idt.r_reg)); + + } + */ + // also determine if CPU supports nested paging - if (vm_info.page_tables) { + if (vm_info.page_tables) { + // if (0) { // Flush the TLB on entries/exits ctrl_area->TLB_CONTROL = 1; // Enable Nested Paging ctrl_area->NP_ENABLE = 1; + PrintDebug("NP_Enable at 0x%x\n", &(ctrl_area->NP_ENABLE)); + // Set the Nested Page Table pointer ctrl_area->N_CR3 |= ((addr_t)vm_info.page_tables & 0xfffff000); - - guest_state->cr3 = Get_CR3(); - PrintDebug("Set Nested CR3: lo: 0x%x hi: 0x%x\n", (uint_t)*(&(ctrl_area->N_CR3)), (uint_t)*(&(ctrl_area->N_CR3) + 4)); - PrintDebug("Set Guest CR3: lo: 0x%x hi: 0x%x\n", (uint_t)*(&(guest_state->cr3)), (uint_t)*(&(guest_state->cr3) + 4)); + + // ctrl_area->N_CR3 = Get_CR3(); + // guest_state->cr3 |= (Get_CR3() & 0xfffff000); + + guest_state->g_pat = 0x7040600070406ULL; + + PrintDebug("Set Nested CR3: lo: 0x%x hi: 0x%x\n", (uint_t)*(&(ctrl_area->N_CR3)), (uint_t)*((unsigned char *)&(ctrl_area->N_CR3) + 4)); + PrintDebug("Set Guest CR3: lo: 0x%x hi: 0x%x\n", (uint_t)*(&(guest_state->cr3)), (uint_t)*((unsigned char *)&(guest_state->cr3) + 4)); // Enable Paging - guest_state->cr0 |= 0x80000000; + // guest_state->cr0 |= 0x80000000; } diff --git a/palacios/src/geekos/svm_lowlevel.asm b/palacios/src/geekos/svm_lowlevel.asm index 57ea853..fcb495f 100644 --- a/palacios/src/geekos/svm_lowlevel.asm +++ b/palacios/src/geekos/svm_lowlevel.asm @@ -8,6 +8,10 @@ %include "symbol.asm" +EXPORT GetGDTR +EXPORT GetIDTR + + EXTERN handle_svm_exit @@ -30,6 +34,32 @@ EXPORT launch_svm +GetGDTR: + push ebp + mov ebp, esp + pusha + mov ebx, [ebp + 8] + sgdt [ebx] + + popa + pop ebp + ret + + + +GetIDTR: + push ebp + mov ebp, esp + pusha + mov ebx, [ebp + 8] + sgdt [ebx] + + popa + pop ebp + ret + + + ; I think its safe to say that there are some pretty serious register issues... launch_svm: push ebp @@ -43,9 +73,6 @@ launch_svm: pop ebp ret -%endif - - ; eventual svm_launch @@ -88,4 +115,9 @@ safe_svm_launch: popf popa pop ebp - ret \ No newline at end of file + ret + + +%endif + + diff --git a/palacios/src/geekos/vmcb.c b/palacios/src/geekos/vmcb.c index 66a7c9c..cfaa2b3 100644 --- a/palacios/src/geekos/vmcb.c +++ b/palacios/src/geekos/vmcb.c @@ -1,4 +1,325 @@ #include +#include +#include +void PrintDebugVMCB(vmcb_t * vmcb) { + reg_ex_t tmp_reg; + vmcb_ctrl_t * ctrl_area = GET_VMCB_CTRL_AREA(vmcb); + vmcb_saved_state_t * guest_area = GET_VMCB_SAVE_STATE_AREA(vmcb); + + PrintDebug("VMCB (0x%.8x)\n", vmcb); + + PrintDebug("--Control Area--\n"); + PrintDebug("CR Reads: %x\n", ctrl_area->cr_reads.bitmap); + PrintDebug("CR Writes: %x\n", ctrl_area->cr_writes.bitmap); + PrintDebug("DR Reads: %x\n", ctrl_area->dr_reads.bitmap); + PrintDebug("DR Writes: %x\n", ctrl_area->dr_writes.bitmap); + + PrintDebug("Exception Bitmap: %x (at 0x%.8x)\n", ctrl_area->exceptions.bitmap, &(ctrl_area->exceptions)); + PrintDebug("\tDivide-by-Zero: %d\n", ctrl_area->exceptions.ex_names.de); + PrintDebug("\tDebug: %d\n", ctrl_area->exceptions.ex_names.db); + PrintDebug("\tNon-maskable interrupts: %d\n", ctrl_area->exceptions.ex_names.nmi); + PrintDebug("\tBreakpoint: %d\n", ctrl_area->exceptions.ex_names.bp); + PrintDebug("\tOverflow: %d\n", ctrl_area->exceptions.ex_names.of); + PrintDebug("\tBound-Range: %d\n", ctrl_area->exceptions.ex_names.br); + PrintDebug("\tInvalid Opcode: %d\n", ctrl_area->exceptions.ex_names.ud); + PrintDebug("\tDevice not available: %d\n", ctrl_area->exceptions.ex_names.nm); + PrintDebug("\tDouble Fault: %d\n", ctrl_area->exceptions.ex_names.df); + PrintDebug("\tInvalid TSS: %d\n", ctrl_area->exceptions.ex_names.ts); + PrintDebug("\tSegment not present: %d\n", ctrl_area->exceptions.ex_names.np); + PrintDebug("\tStack: %d\n", ctrl_area->exceptions.ex_names.ss); + PrintDebug("\tGPF: %d\n", ctrl_area->exceptions.ex_names.gp); + PrintDebug("\tPage Fault: %d\n", ctrl_area->exceptions.ex_names.pf); + PrintDebug("\tFloating Point: %d\n", ctrl_area->exceptions.ex_names.mf); + PrintDebug("\tAlignment Check: %d\n", ctrl_area->exceptions.ex_names.ac); + PrintDebug("\tMachine Check: %d\n", ctrl_area->exceptions.ex_names.mc); + PrintDebug("\tSIMD floating point: %d\n", ctrl_area->exceptions.ex_names.xf); + PrintDebug("\tSecurity: %d\n", ctrl_area->exceptions.ex_names.sx); + + PrintDebug("Instructions bitmap: %.8x (at 0x%.8x)\n", ctrl_area->instrs.bitmap, &(ctrl_area->instrs)); + PrintDebug("\tINTR: %d\n", ctrl_area->instrs.instrs.INTR); + PrintDebug("\tNMI: %d\n", ctrl_area->instrs.instrs.NMI); + PrintDebug("\tSMI: %d\n", ctrl_area->instrs.instrs.SMI); + PrintDebug("\tINIT: %d\n", ctrl_area->instrs.instrs.INIT); + PrintDebug("\tVINTR: %d\n", ctrl_area->instrs.instrs.VINTR); + PrintDebug("\tCR0: %d\n", ctrl_area->instrs.instrs.CR0); + PrintDebug("\tRD_IDTR: %d\n", ctrl_area->instrs.instrs.RD_IDTR); + PrintDebug("\tRD_GDTR: %d\n", ctrl_area->instrs.instrs.RD_GDTR); + PrintDebug("\tRD_LDTR: %d\n", ctrl_area->instrs.instrs.RD_LDTR); + PrintDebug("\tRD_TR: %d\n", ctrl_area->instrs.instrs.RD_TR); + PrintDebug("\tWR_IDTR: %d\n", ctrl_area->instrs.instrs.WR_IDTR); + PrintDebug("\tWR_GDTR: %d\n", ctrl_area->instrs.instrs.WR_GDTR); + PrintDebug("\tWR_LDTR: %d\n", ctrl_area->instrs.instrs.WR_LDTR); + PrintDebug("\tWR_TR: %d\n", ctrl_area->instrs.instrs.WR_TR); + PrintDebug("\tRDTSC: %d\n", ctrl_area->instrs.instrs.RDTSC); + PrintDebug("\tRDPMC: %d\n", ctrl_area->instrs.instrs.RDPMC); + PrintDebug("\tPUSHF: %d\n", ctrl_area->instrs.instrs.PUSHF); + PrintDebug("\tPOPF: %d\n", ctrl_area->instrs.instrs.POPF); + PrintDebug("\tCPUID: %d\n", ctrl_area->instrs.instrs.CPUID); + PrintDebug("\tRSM: %d\n", ctrl_area->instrs.instrs.RSM); + PrintDebug("\tIRET: %d\n", ctrl_area->instrs.instrs.IRET); + PrintDebug("\tINTn: %d\n", ctrl_area->instrs.instrs.INTn); + PrintDebug("\tINVD: %d\n", ctrl_area->instrs.instrs.INVD); + PrintDebug("\tPAUSE: %d\n", ctrl_area->instrs.instrs.PAUSE); + PrintDebug("\tHLT: %d\n", ctrl_area->instrs.instrs.HLT); + PrintDebug("\tINVPLG: %d\n", ctrl_area->instrs.instrs.INVPLG); + PrintDebug("\tINVPLGA: %d\n", ctrl_area->instrs.instrs.INVPLGA); + PrintDebug("\tIOIO_PROT: %d\n", ctrl_area->instrs.instrs.IOIO_PROT); + PrintDebug("\tMSR_PROT: %d\n", ctrl_area->instrs.instrs.MSR_PROT); + PrintDebug("\ttask_switch: %d\n", ctrl_area->instrs.instrs.task_switch); + PrintDebug("\tFERR_FREEZE: %d\n", ctrl_area->instrs.instrs.FERR_FREEZE); + PrintDebug("\tshutdown_evts: %d\n", ctrl_area->instrs.instrs.shutdown_evts); + + PrintDebug("SVM Instruction Bitmap: %.8x (at 0x%.8x)\n", ctrl_area->svm_instrs.bitmap, &(ctrl_area->svm_instrs)); + PrintDebug("\tVMRUN: %d\n", ctrl_area->svm_instrs.instrs.VMRUN); + PrintDebug("\tVMMCALL: %d\n", ctrl_area->svm_instrs.instrs.VMMCALL); + PrintDebug("\tVMLOAD: %d\n", ctrl_area->svm_instrs.instrs.VMLOAD); + PrintDebug("\tVMSAVE: %d\n", ctrl_area->svm_instrs.instrs.VMSAVE); + PrintDebug("\tSTGI: %d\n", ctrl_area->svm_instrs.instrs.STGI); + PrintDebug("\tCLGI: %d\n", ctrl_area->svm_instrs.instrs.CLGI); + PrintDebug("\tSKINIT: %d\n", ctrl_area->svm_instrs.instrs.SKINIT); + PrintDebug("\tRDTSCP: %d\n", ctrl_area->svm_instrs.instrs.RDTSCP); + PrintDebug("\tICEBP: %d\n", ctrl_area->svm_instrs.instrs.ICEBP); + PrintDebug("\tWBINVD: %d\n", ctrl_area->svm_instrs.instrs.WBINVD); + PrintDebug("\tMONITOR: %d\n", ctrl_area->svm_instrs.instrs.MONITOR); + PrintDebug("\tMWAIT_always: %d\n", ctrl_area->svm_instrs.instrs.MWAIT_always); + PrintDebug("\tMWAIT_if_armed: %d\n", ctrl_area->svm_instrs.instrs.MWAIT_if_armed); + + + + tmp_reg.r_reg = ctrl_area->IOPM_BASE_PA; + PrintDebug("IOPM_BASE_PA: lo: 0x%.8x, hi: 0x%.8x\n", tmp_reg.e_reg.low, tmp_reg.e_reg.high); + tmp_reg.r_reg = ctrl_area->MSRPM_BASE_PA; + PrintDebug("MSRPM_BASE_PA: lo: 0x%.8x, hi: 0x%.8x\n", tmp_reg.e_reg.low, tmp_reg.e_reg.high); + tmp_reg.r_reg = ctrl_area->TSC_OFFSET; + PrintDebug("TSC_OFFSET: lo: 0x%.8x, hi: 0x%.8x\n", tmp_reg.e_reg.low, tmp_reg.e_reg.high); + + PrintDebug("guest_ASID: %d\n", ctrl_area->guest_ASID); + PrintDebug("TLB_CONTROL: %d\n", ctrl_area->TLB_CONTROL); + + + PrintDebug("Guest Control Bitmap: %x (at 0x%.8x)\n", ctrl_area->guest_ctrl.bitmap, &(ctrl_area->guest_ctrl)); + PrintDebug("\tV_TPR: %d\n", ctrl_area->guest_ctrl.ctrls.V_TPR); + PrintDebug("\tV_IRQ: %d\n", ctrl_area->guest_ctrl.ctrls.V_IRQ); + PrintDebug("\tV_INTR_PRIO: %d\n", ctrl_area->guest_ctrl.ctrls.V_INTR_PRIO); + PrintDebug("\tV_IGN_TPR: %d\n", ctrl_area->guest_ctrl.ctrls.V_IGN_TPR); + PrintDebug("\tV_INTR_MASKING: %d\n", ctrl_area->guest_ctrl.ctrls.V_INTR_MASKING); + PrintDebug("\tV_INTR_VECTOR: %d\n", ctrl_area->guest_ctrl.ctrls.V_INTR_VECTOR); + + PrintDebug("Interrupt_shadow: %d\n", ctrl_area->interrupt_shadow); + + + tmp_reg.r_reg = ctrl_area->exit_code; + PrintDebug("exit_code: hi: 0x%.8x, lo: 0x%.8x\n", tmp_reg.e_reg.high, tmp_reg.e_reg.low); + tmp_reg.r_reg = ctrl_area->exit_info1; + PrintDebug("exit_info1: hi: 0x%.8x, lo: 0x%.8x\n", tmp_reg.e_reg.high, tmp_reg.e_reg.low); + tmp_reg.r_reg = ctrl_area->exit_info2; + PrintDebug("exit_info2: hi: 0x%.8x, lo: 0x%.8x\n", tmp_reg.e_reg.high, tmp_reg.e_reg.low); + + tmp_reg.r_reg = ctrl_area->exit_int_info; + PrintDebug("exit_int_info: hi: 0x%.8x, lo: 0x%.8x\n", tmp_reg.e_reg.high, tmp_reg.e_reg.low); + + + tmp_reg.r_reg = ctrl_area->NP_ENABLE; + PrintDebug("NP_ENABLE: hi: 0x%.8x, lo: 0x%.8x\n", tmp_reg.e_reg.high, tmp_reg.e_reg.low); + + tmp_reg.r_reg = ctrl_area->EVENTINJ; + PrintDebug("EVENTINJ: hi: 0x%.8x, lo: 0x%.8x\n", tmp_reg.e_reg.high, tmp_reg.e_reg.low); + + + tmp_reg.r_reg = ctrl_area->N_CR3; + PrintDebug("N_CR3: hi: 0x%.8x, lo: 0x%.8x\n", tmp_reg.e_reg.high, tmp_reg.e_reg.low); + + PrintDebug("LBR_VIRTUALIZATION_ENABLE: %d\n", ctrl_area->LBR_VIRTUALIZATION_ENABLE); + + + PrintDebug("\n--Guest Saved State--\n"); + + PrintDebug("es Selector (at 0x%.8x): \n", &(guest_area->es)); + PrintDebug("\tSelector: %d\n", guest_area->es.selector); + PrintDebug("\t(type=%x), (S=%d), (dpl=%d), (P=%d), (avl=%d), (L=%d), (db=%d), (G=%d)\n", + guest_area->es.attrib.fields.type, guest_area->es.attrib.fields.S, + guest_area->es.attrib.fields.dpl, guest_area->es.attrib.fields.P, + guest_area->es.attrib.fields.avl, guest_area->es.attrib.fields.L, + guest_area->es.attrib.fields.db, guest_area->es.attrib.fields.G); + PrintDebug("\tlimit: %lu\n", guest_area->es.limit); + tmp_reg.r_reg = guest_area->es.base; + PrintDebug("\tBase: hi: 0x%.8x, lo: 0x%.8x\n", tmp_reg.e_reg.high, tmp_reg.e_reg.low); + + + PrintDebug("cs Selector (at 0x%.8x): \n", &(guest_area->cs)); + PrintDebug("\tSelector: %d\n", guest_area->cs.selector); + PrintDebug("\t(type=%x), (S=%d), (dpl=%d), (P=%d), (avl=%d), (L=%d), (db=%d), (G=%d)\n", + guest_area->cs.attrib.fields.type, guest_area->cs.attrib.fields.S, + guest_area->cs.attrib.fields.dpl, guest_area->cs.attrib.fields.P, + guest_area->cs.attrib.fields.avl, guest_area->cs.attrib.fields.L, + guest_area->cs.attrib.fields.db, guest_area->cs.attrib.fields.G); + PrintDebug("\tlimit: %lu\n", guest_area->cs.limit); + tmp_reg.r_reg = guest_area->cs.base; + PrintDebug("\tBase: hi: 0x%.8x, lo: 0x%.8x\n", tmp_reg.e_reg.high, tmp_reg.e_reg.low); + + + PrintDebug("ss Selector (at 0x%.8x): \n", &(guest_area->ss)); + PrintDebug("\tSelector: %d\n", guest_area->ss.selector); + PrintDebug("\t(type=%x), (S=%d), (dpl=%d), (P=%d), (avl=%d), (L=%d), (db=%d), (G=%d)\n", + guest_area->ss.attrib.fields.type, guest_area->ss.attrib.fields.S, + guest_area->ss.attrib.fields.dpl, guest_area->ss.attrib.fields.P, + guest_area->ss.attrib.fields.avl, guest_area->ss.attrib.fields.L, + guest_area->ss.attrib.fields.db, guest_area->ss.attrib.fields.G); + PrintDebug("\tlimit: %lu\n", guest_area->ss.limit); + tmp_reg.r_reg = guest_area->ss.base; + PrintDebug("\tBase: hi: 0x%.8x, lo: 0x%.8x\n", tmp_reg.e_reg.high, tmp_reg.e_reg.low); + + + PrintDebug("ds Selector (at 0x%.8x): \n", &(guest_area->ds)); + PrintDebug("\tSelector: %d\n", guest_area->ds.selector); + PrintDebug("\t(type=%x), (S=%d), (dpl=%d), (P=%d), (avl=%d), (L=%d), (db=%d), (G=%d)\n", + guest_area->ds.attrib.fields.type, guest_area->ds.attrib.fields.S, + guest_area->ds.attrib.fields.dpl, guest_area->ds.attrib.fields.P, + guest_area->ds.attrib.fields.avl, guest_area->ds.attrib.fields.L, + guest_area->ds.attrib.fields.db, guest_area->ds.attrib.fields.G); + PrintDebug("\tlimit: %lu\n", guest_area->ds.limit); + tmp_reg.r_reg = guest_area->ds.base; + PrintDebug("\tBase: hi: 0x%.8x, lo: 0x%.8x\n", tmp_reg.e_reg.high, tmp_reg.e_reg.low); + + + PrintDebug("fs Selector (at 0x%.8x): \n", &(guest_area->fs)); + PrintDebug("\tSelector: %d\n", guest_area->fs.selector); + PrintDebug("\t(type=%x), (S=%d), (dpl=%d), (P=%d), (avl=%d), (L=%d), (db=%d), (G=%d)\n", + guest_area->fs.attrib.fields.type, guest_area->fs.attrib.fields.S, + guest_area->fs.attrib.fields.dpl, guest_area->fs.attrib.fields.P, + guest_area->fs.attrib.fields.avl, guest_area->fs.attrib.fields.L, + guest_area->fs.attrib.fields.db, guest_area->fs.attrib.fields.G); + PrintDebug("\tlimit: %lu\n", guest_area->fs.limit); + tmp_reg.r_reg = guest_area->fs.base; + PrintDebug("\tBase: hi: 0x%.8x, lo: 0x%.8x\n", tmp_reg.e_reg.high, tmp_reg.e_reg.low); + + + PrintDebug("gs Selector (at 0x%.8x): \n", &(guest_area->gs)); + PrintDebug("\tSelector: %d\n", guest_area->gs.selector); + PrintDebug("\t(type=%x), (S=%d), (dpl=%d), (P=%d), (avl=%d), (L=%d), (db=%d), (G=%d)\n", + guest_area->gs.attrib.fields.type, guest_area->gs.attrib.fields.S, + guest_area->gs.attrib.fields.dpl, guest_area->gs.attrib.fields.P, + guest_area->gs.attrib.fields.avl, guest_area->gs.attrib.fields.L, + guest_area->gs.attrib.fields.db, guest_area->gs.attrib.fields.G); + PrintDebug("\tlimit: %lu\n", guest_area->gs.limit); + tmp_reg.r_reg = guest_area->gs.base; + PrintDebug("\tBase: hi: 0x%.8x, lo: 0x%.8x\n", tmp_reg.e_reg.high, tmp_reg.e_reg.low); + + + PrintDebug("gdtr Selector (at 0x%.8x): \n", &(guest_area->gdtr)); + PrintDebug("\tSelector: %d\n", guest_area->gdtr.selector); + PrintDebug("\t(type=%x), (S=%d), (dpl=%d), (P=%d), (avl=%d), (L=%d), (db=%d), (G=%d)\n", + guest_area->gdtr.attrib.fields.type, guest_area->gdtr.attrib.fields.S, + guest_area->gdtr.attrib.fields.dpl, guest_area->gdtr.attrib.fields.P, + guest_area->gdtr.attrib.fields.avl, guest_area->gdtr.attrib.fields.L, + guest_area->gdtr.attrib.fields.db, guest_area->gdtr.attrib.fields.G); + PrintDebug("\tlimit: %lu\n", guest_area->gdtr.limit); + tmp_reg.r_reg = guest_area->gdtr.base; + PrintDebug("\tBase: hi: 0x%.8x, lo: 0x%.8x\n", tmp_reg.e_reg.high, tmp_reg.e_reg.low); + + + PrintDebug("ldtr Selector (at 0x%.8x): \n", &(guest_area->ldtr)); + PrintDebug("\tSelector: %d\n", guest_area->ldtr.selector); + PrintDebug("\t(type=%x), (S=%d), (dpl=%d), (P=%d), (avl=%d), (L=%d), (db=%d), (G=%d)\n", + guest_area->ldtr.attrib.fields.type, guest_area->ldtr.attrib.fields.S, + guest_area->ldtr.attrib.fields.dpl, guest_area->ldtr.attrib.fields.P, + guest_area->ldtr.attrib.fields.avl, guest_area->ldtr.attrib.fields.L, + guest_area->ldtr.attrib.fields.db, guest_area->ldtr.attrib.fields.G); + PrintDebug("\tlimit: %lu\n", guest_area->ldtr.limit); + tmp_reg.r_reg = guest_area->ldtr.base; + PrintDebug("\tBase: hi: 0x%.8x, lo: 0x%.8x\n", tmp_reg.e_reg.high, tmp_reg.e_reg.low); + + + PrintDebug("idtr Selector (at 0x%.8x): \n", &(guest_area->idtr)); + PrintDebug("\tSelector: %d\n", guest_area->idtr.selector); + PrintDebug("\t(type=%x), (S=%d), (dpl=%d), (P=%d), (avl=%d), (L=%d), (db=%d), (G=%d)\n", + guest_area->idtr.attrib.fields.type, guest_area->idtr.attrib.fields.S, + guest_area->idtr.attrib.fields.dpl, guest_area->idtr.attrib.fields.P, + guest_area->idtr.attrib.fields.avl, guest_area->idtr.attrib.fields.L, + guest_area->idtr.attrib.fields.db, guest_area->idtr.attrib.fields.G); + PrintDebug("\tlimit: %lu\n", guest_area->idtr.limit); + tmp_reg.r_reg = guest_area->idtr.base; + PrintDebug("\tBase: hi: 0x%.8x, lo: 0x%.8x\n", tmp_reg.e_reg.high, tmp_reg.e_reg.low); + + + PrintDebug("tr Selector (at 0x%.8x): \n", &(guest_area->tr)); + PrintDebug("\tSelector: %d\n", guest_area->tr.selector); + PrintDebug("\t(type=%x), (S=%d), (dpl=%d), (P=%d), (avl=%d), (L=%d), (db=%d), (G=%d)\n", + guest_area->tr.attrib.fields.type, guest_area->tr.attrib.fields.S, + guest_area->tr.attrib.fields.dpl, guest_area->tr.attrib.fields.P, + guest_area->tr.attrib.fields.avl, guest_area->tr.attrib.fields.L, + guest_area->tr.attrib.fields.db, guest_area->tr.attrib.fields.G); + PrintDebug("\tlimit: %lu\n", guest_area->tr.limit); + tmp_reg.r_reg = guest_area->tr.base; + PrintDebug("\tBase: hi: 0x%.8x, lo: 0x%.8x\n", tmp_reg.e_reg.high, tmp_reg.e_reg.low); + + + PrintDebug("cpl: %d\n", guest_area->cpl); + + + tmp_reg.r_reg = guest_area->efer; + PrintDebug("EFER: hi: 0x%.8x, lo: 0x%.8x\n", tmp_reg.e_reg.high, tmp_reg.e_reg.low); + + tmp_reg.r_reg = guest_area->cr4; + PrintDebug("CR4: hi: 0x%.8x, lo: 0x%.8x\n", tmp_reg.e_reg.high, tmp_reg.e_reg.low); + tmp_reg.r_reg = guest_area->cr3; + PrintDebug("CR3: hi: 0x%.8x, lo: 0x%.8x\n", tmp_reg.e_reg.high, tmp_reg.e_reg.low); + tmp_reg.r_reg = guest_area->cr0; + PrintDebug("CR0: hi: 0x%.8x, lo: 0x%.8x\n", tmp_reg.e_reg.high, tmp_reg.e_reg.low); + tmp_reg.r_reg = guest_area->dr7; + PrintDebug("DR7: hi: 0x%.8x, lo: 0x%.8x\n", tmp_reg.e_reg.high, tmp_reg.e_reg.low); + tmp_reg.r_reg = guest_area->dr6; + PrintDebug("DR6: hi: 0x%.8x, lo: 0x%.8x\n", tmp_reg.e_reg.high, tmp_reg.e_reg.low); + tmp_reg.r_reg = guest_area->rflags; + PrintDebug("RFLAGS: hi: 0x%.8x, lo: 0x%.8x\n", tmp_reg.e_reg.high, tmp_reg.e_reg.low); + tmp_reg.r_reg = guest_area->rip; + PrintDebug("RIP: hi: 0x%.8x, lo: 0x%.8x\n", tmp_reg.e_reg.high, tmp_reg.e_reg.low); + + + tmp_reg.r_reg = guest_area->rsp; + PrintDebug("RSP: hi: 0x%.8x, lo: 0x%.8x\n", tmp_reg.e_reg.high, tmp_reg.e_reg.low); + + + tmp_reg.r_reg = guest_area->rax; + PrintDebug("RAX: hi: 0x%.8x, lo: 0x%.8x\n", tmp_reg.e_reg.high, tmp_reg.e_reg.low); + tmp_reg.r_reg = guest_area->star; + PrintDebug("STAR: hi: 0x%.8x, lo: 0x%.8x\n", tmp_reg.e_reg.high, tmp_reg.e_reg.low); + tmp_reg.r_reg = guest_area->lstar; + PrintDebug("LSTAR: hi: 0x%.8x, lo: 0x%.8x\n", tmp_reg.e_reg.high, tmp_reg.e_reg.low); + tmp_reg.r_reg = guest_area->cstar; + PrintDebug("CSTAR: hi: 0x%.8x, lo: 0x%.8x\n", tmp_reg.e_reg.high, tmp_reg.e_reg.low); + tmp_reg.r_reg = guest_area->sfmask; + PrintDebug("SFMASK: hi: 0x%.8x, lo: 0x%.8x\n", tmp_reg.e_reg.high, tmp_reg.e_reg.low); + tmp_reg.r_reg = guest_area->KernelGsBase; + PrintDebug("KernelGsBase: hi: 0x%.8x, lo: 0x%.8x\n", tmp_reg.e_reg.high, tmp_reg.e_reg.low); + tmp_reg.r_reg = guest_area->sysenter_cs; + PrintDebug("sysenter_cs: hi: 0x%.8x, lo: 0x%.8x\n", tmp_reg.e_reg.high, tmp_reg.e_reg.low); + tmp_reg.r_reg = guest_area->sysenter_esp; + PrintDebug("sysenter_esp: hi: 0x%.8x, lo: 0x%.8x\n", tmp_reg.e_reg.high, tmp_reg.e_reg.low); + tmp_reg.r_reg = guest_area->sysenter_eip; + PrintDebug("sysenter_eip: hi: 0x%.8x, lo: 0x%.8x\n", tmp_reg.e_reg.high, tmp_reg.e_reg.low); + tmp_reg.r_reg = guest_area->cr2; + PrintDebug("CR2: hi: 0x%.8x, lo: 0x%.8x\n", tmp_reg.e_reg.high, tmp_reg.e_reg.low); + + tmp_reg.r_reg = guest_area->g_pat; + PrintDebug("g_pat: hi: 0x%.8x, lo: 0x%.8x\n", tmp_reg.e_reg.high, tmp_reg.e_reg.low); + tmp_reg.r_reg = guest_area->dbgctl; + PrintDebug("dbgctl: hi: 0x%.8x, lo: 0x%.8x\n", tmp_reg.e_reg.high, tmp_reg.e_reg.low); + tmp_reg.r_reg = guest_area->br_from; + PrintDebug("br_from: hi: 0x%.8x, lo: 0x%.8x\n", tmp_reg.e_reg.high, tmp_reg.e_reg.low); + tmp_reg.r_reg = guest_area->br_to; + PrintDebug("br_to: hi: 0x%.8x, lo: 0x%.8x\n", tmp_reg.e_reg.high, tmp_reg.e_reg.low); + tmp_reg.r_reg = guest_area->lastexcpfrom; + PrintDebug("lastexcpfrom: hi: 0x%.8x, lo: 0x%.8x\n", tmp_reg.e_reg.high, tmp_reg.e_reg.low); + tmp_reg.r_reg = guest_area->lastexcpto; + PrintDebug("lastexcpto: hi: 0x%.8x, lo: 0x%.8x\n", tmp_reg.e_reg.high, tmp_reg.e_reg.low); + + + + + + +} diff --git a/palacios/src/geekos/vmm_paging.c b/palacios/src/geekos/vmm_paging.c index 879d68a..2a8575f 100644 --- a/palacios/src/geekos/vmm_paging.c +++ b/palacios/src/geekos/vmm_paging.c @@ -216,3 +216,196 @@ void PrintDebugPageTables(vmm_pde_t * pde) } + + + +pml4e64_t * generate_guest_page_tables_64(vmm_mem_layout_t * layout, vmm_mem_list_t * list) { + pml4e64_t * pml = os_hooks->allocate_pages(1); + int i, j, k, m; + ullong_t current_page_addr = 0; + uint_t layout_index = 0; + uint_t list_index = 0; + ullong_t layout_addr = 0; + uint_t num_entries = layout->num_pages; // The number of pages left in the layout + + for (m = 0; m < MAX_PAGE_MAP_ENTRIES_64; m++ ) { + if (num_entries == 0) { + pml[m].present = 0; + pml[m].writable = 0; + pml[m].user = 0; + pml[m].pwt = 0; + pml[m].pcd = 0; + pml[m].accessed = 0; + pml[m].reserved = 0; + pml[m].zero = 0; + pml[m].vmm_info = 0; + pml[m].pdp_base_addr_lo = 0; + pml[m].pdp_base_addr_hi = 0; + pml[m].available = 0; + pml[m].no_execute = 0; + } else { + pdpe64_t * pdpe = os_hooks->allocate_pages(1); + + pml[m].present = 1; + pml[m].writable = 1; + pml[m].user = 1; + pml[m].pwt = 0; + pml[m].pcd = 0; + pml[m].accessed = 0; + pml[m].reserved = 0; + pml[m].zero = 0; + pml[m].vmm_info = 0; + pml[m].pdp_base_addr_lo = PAGE_ALLIGNED_ADDR(pdpe) & 0xfffff; + pml[m].pdp_base_addr_hi = 0; + pml[m].available = 0; + pml[m].no_execute = 0; + + for (k = 0; k < MAX_PAGE_DIR_PTR_ENTRIES_64; k++) { + if (num_entries == 0) { + pdpe[k].present = 0; + pdpe[k].writable = 0; + pdpe[k].user = 0; + pdpe[k].pwt = 0; + pdpe[k].pcd = 0; + pdpe[k].accessed = 0; + pdpe[k].reserved = 0; + pdpe[k].large_pages = 0; + pdpe[k].zero = 0; + pdpe[k].vmm_info = 0; + pdpe[k].pd_base_addr_lo = 0; + pdpe[k].pd_base_addr_hi = 0; + pdpe[k].available = 0; + pdpe[k].no_execute = 0; + } else { + pde64_t * pde = os_hooks->allocate_pages(1); + + pdpe[k].present = 1; + pdpe[k].writable = 1; + pdpe[k].user = 1; + pdpe[k].pwt = 0; + pdpe[k].pcd = 0; + pdpe[k].accessed = 0; + pdpe[k].reserved = 0; + pdpe[k].large_pages = 0; + pdpe[k].zero = 0; + pdpe[k].vmm_info = 0; + pdpe[k].pd_base_addr_lo = PAGE_ALLIGNED_ADDR(pde) & 0xfffff; + pdpe[k].pd_base_addr_hi = 0; + pdpe[k].available = 0; + pdpe[k].no_execute = 0; + + + + for (i = 0; i < MAX_PAGE_DIR_ENTRIES_64; i++) { + if (num_entries == 0) { + pde[i].present = 0; + pde[i].flags = 0; + pde[i].accessed = 0; + pde[i].reserved = 0; + pde[i].large_pages = 0; + pde[i].reserved2 = 0; + pde[i].vmm_info = 0; + pde[i].pt_base_addr_lo = 0; + pde[i].pt_base_addr_hi = 0; + pde[i].available = 0; + pde[i].no_execute = 0; + } else { + pte64_t * pte = os_hooks->allocate_pages(1); + + pde[i].present = 1; + pde[i].flags = VM_READ | VM_WRITE | VM_EXEC | VM_USER; + pde[i].accessed = 0; + pde[i].reserved = 0; + pde[i].large_pages = 0; + pde[i].reserved2 = 0; + pde[i].vmm_info = 0; + pde[i].pt_base_addr_lo = PAGE_ALLIGNED_ADDR(pte) & 0xfffff; + pde[i].pt_base_addr_hi = 0; + pde[i].available = 0; + pde[i].no_execute = 0; + + + for (j = 0; j < MAX_PAGE_TABLE_ENTRIES_64; j++) { + layout_addr = get_mem_layout_addr(layout, layout_index); + + if ((current_page_addr < layout_addr) || (num_entries == 0)) { + // We have a gap in the layout, fill with unmapped page + pte[j].present = 0; + pte[j].flags = 0; + pte[j].accessed = 0; + pte[j].dirty = 0; + pte[j].pte_attr = 0; + pte[j].global_page = 0; + pte[j].vmm_info = 0; + pte[j].page_base_addr_lo = 0; + pte[j].page_base_addr_hi = 0; + pte[j].available = 0; + pte[j].no_execute = 0; + + current_page_addr += PAGE_SIZE; + } else if (current_page_addr == layout_addr) { + // Set up the Table entry to map correctly to the layout region + layout_region_t * page_region = get_mem_layout_region(layout, layout_addr); + + if (page_region->type == UNMAPPED) { + pte[j].present = 0; + pte[j].flags = 0; + } else { + pte[j].present = 1; + pte[j].flags = VM_READ | VM_WRITE | VM_EXEC | VM_USER; + } + + pte[j].accessed = 0; + pte[j].dirty = 0; + pte[j].pte_attr = 0; + pte[j].global_page = 0; + pte[j].vmm_info = 0; + pte[j].available = 0; + pte[j].no_execute = 0; + + if (page_region->type == UNMAPPED) { + pte[j].page_base_addr_lo = 0; + pte[j].page_base_addr_hi = 0; + } else if (page_region->type == SHARED) { + addr_t host_addr = page_region->host_addr + (layout_addr - page_region->start); + + pte[j].page_base_addr_lo = PAGE_ALLIGNED_ADDR(host_addr) & 0xfffff; + pte[j].page_base_addr_hi = 0; + pte[j].vmm_info = SHARED_PAGE; + } else if (page_region->type == GUEST) { + addr_t list_addr = get_mem_list_addr(list, list_index++); + + if (list_addr == -1) { + // error + // cleanup... + //free_guest_page_tables(pde); + return NULL; + } + PrintDebug("Adding guest page (%x)\n", list_addr); + pte[j].page_base_addr_lo = PAGE_ALLIGNED_ADDR(list_addr) & 0xfffff; + pte[j].page_base_addr_hi = 0; + + // Reset this when we move over to dynamic page allocation + // pte[j].vmm_info = GUEST_PAGE; + pte[j].vmm_info = SHARED_PAGE; + } + + num_entries--; + current_page_addr += PAGE_SIZE; + layout_index++; + } else { + // error + PrintDebug("Error creating page table...\n"); + // cleanup + // free_guest_page_tables64(pde); + return NULL; + } + } + } + } + } + } + } + } + return pml; +} diff --git a/palacios/src/geekos/vmm_stubs.c b/palacios/src/geekos/vmm_stubs.c index fb52584..96145db 100644 --- a/palacios/src/geekos/vmm_stubs.c +++ b/palacios/src/geekos/vmm_stubs.c @@ -1,9 +1,31 @@ #include - +#include void * Allocate_VMM_Pages(int num_pages) { - return Alloc_Page(); + void * start_page = Alloc_Page(); + SerialPrint("Allocating Page: %x (%d of %d)\n",start_page, 1, num_pages); + int i = 1; + + while (i < num_pages) { + void * tmp_page = Alloc_Page(); + SerialPrint("Allocating Page: %x (%d of %d)\n",tmp_page, i+1, num_pages); + + if (tmp_page != start_page + (PAGE_SIZE * i)) { + //we have to start over...; + while (i >= 0) { + Free_Page(start_page + (PAGE_SIZE * i)); + i--; + } + start_page = Alloc_Page(); + SerialPrint("Allocating Page: %x (%d of %d)\n",start_page, 1, num_pages); + i = 1; + continue; + } + i++; + } + + return start_page; } void Free_VMM_Page(void * page) {