From: Jack Lange Date: Tue, 1 Apr 2008 22:55:04 +0000 (+0000) Subject: working on x86 instruction decoding support X-Git-Tag: working-cdboot-physical-but-not-qemu~48 X-Git-Url: http://v3vee.org/palacios/gitweb/gitweb.cgi?p=palacios.git;a=commitdiff_plain;h=959ed075fac59969a8dc299e51824166f50bb2d0 working on x86 instruction decoding support --- diff --git a/palacios/include/geekos/svm_ctrl_regs.h b/palacios/include/geekos/svm_ctrl_regs.h index d16e46f..d8b3e37 100644 --- a/palacios/include/geekos/svm_ctrl_regs.h +++ b/palacios/include/geekos/svm_ctrl_regs.h @@ -10,7 +10,9 @@ static const uchar_t cr_access_byte = 0x0f; // Second opcode byte static const uchar_t lmsw_byte = 0x01; +static const uchar_t lmsw_reg_byte = 0x6; static const uchar_t smsw_byte = 0x01; +static const uchar_t smsw_reg_byte = 0x4; static const uchar_t clts_byte = 0x06; static const uchar_t mov_to_cr_byte = 0x22; static const uchar_t mov_from_cr_byte = 0x20; diff --git a/palacios/include/geekos/vm_guest.h b/palacios/include/geekos/vm_guest.h index aee6182..f711b36 100644 --- a/palacios/include/geekos/vm_guest.h +++ b/palacios/include/geekos/vm_guest.h @@ -4,38 +4,50 @@ #include #include #include -//#include - - +#include -struct guest_info; +typedef ullong_t gpr_t; -#include +/* + struct guest_gprs { + addr_t rax; + addr_t rbx; + addr_t rcx; + addr_t rdx; + addr_t rsi; + addr_t rdi; + addr_t rbp; + }; +*/ struct guest_gprs { - ullong_t rbx; - ullong_t rcx; - ullong_t rdx; - ullong_t rsi; - ullong_t rdi; - ullong_t rbp; - + gpr_t rdi; + gpr_t rsi; + gpr_t rbp; + gpr_t rsp; + gpr_t rbx; + gpr_t rdx; + gpr_t rcx; + gpr_t rax; }; +struct shadow_page_state; + + typedef enum {SHADOW_PAGING, NESTED_PAGING} vm_page_mode_t; typedef enum {REAL, PROTECTED, PROTECTED_PG, PROTECTED_PAE, PROTECTED_PAE_PG, LONG, LONG_PG} vm_cpu_mode_t; struct guest_info { ullong_t rip; - ullong_t rsp; + shadow_map_t mem_map; vm_page_mode_t page_mode; - struct shadow_page_state shdw_pg_state; + struct shadow_page_state shdw_pg_state; // nested_paging_t nested_page_state; diff --git a/palacios/include/geekos/vm_guest_mem.h b/palacios/include/geekos/vm_guest_mem.h index f738736..24dbca8 100644 --- a/palacios/include/geekos/vm_guest_mem.h +++ b/palacios/include/geekos/vm_guest_mem.h @@ -85,7 +85,8 @@ int host_va_to_guest_va(struct guest_info * guest_info, addr_t host_va, addr_t int read_guest_va_memory(struct guest_info * guest_info, addr_t guest_va, int count, char * dest); int read_guest_pa_memory(struct guest_info * guest_info, addr_t guest_pa, int count, char * dest); - +int write_guest_pa_memory(struct guest_info * guest_info, addr_t guest_pa, int count, char * src); +// TODO int write_guest_va_memory(struct guest_info * guest_info, addr_t guest_va, int count, char * src); diff --git a/palacios/include/geekos/vmm_emulate.h b/palacios/include/geekos/vmm_emulate.h index 2e87a75..e82777c 100644 --- a/palacios/include/geekos/vmm_emulate.h +++ b/palacios/include/geekos/vmm_emulate.h @@ -1,11 +1,67 @@ #ifndef __VMM_EMULATE_H #define __VMM_EMULATE_H +#include -/* JRL: Most of this was taken from the Xen sources... +/* + * This is where we do the hideous X86 instruction parsing among other things + * We can parse out the instruction prefixes, as well as decode the operands + * + * Before we begin I'd just like to say a few words to those that made this possible... + * + * + * _____ + * || || + * |\___/| + * | | + * | | + * | | + * | | + * | | + * | | + * _____|<--->|_____ + * ___/ | | \ + * / | | | | \ + * | | | | | | + * | | | | | | + * | | | + * | | | + * | Fuck You Intel! / + * | / + * \ / + * \ / + * | | + * | | + * + * That is all. + * + */ + + +/* JRL: Some of this was taken from the Xen sources... * */ +#define PACKED __attribute__((packed)) + +#define MODRM_MOD(x) ((x >> 6) & 0x3) +#define MODRM_REG(x) ((x >> 3) & 0x7) +#define MODRM_RM(x) (x & 0x07) + +struct modrm_byte { + uint_t rm : 3 PACKED; + uint_t reg : 3 PACKED; + uint_t mod : 2 PACKED; +}; + + +struct sib_byte { + uint_t base : 3 PACKED; + uint_t index : 3 PACKED; + uint_t scale : 2 PACKED; +}; + + #define MAKE_INSTR(nm, ...) static const uchar_t OPCODE_##nm[] = { __VA_ARGS__ } @@ -71,6 +127,165 @@ static inline int is_prefix_byte(char byte) { } } +typedef enum {INVALID_ADDR_TYPE, REG, DISP0, DISP8, DISP16, DISP32} modrm_addr_type_t; +typedef enum {INVALID_REG_SIZE, REG64, REG32, REG16, REG8} reg_size_t; +typedef enum {INVALID_OPERAND_TYPE, REG_TO_REG, REG_TO_MEM, MEM_TO_REG} operand_type_t; + +struct guest_gprs; + + +static inline int decode_operands16(struct guest_gprs * gprs, + char * modrm_instr, + addr_t * first_operand, + addr_t * second_operand, + reg_size_t reg_size) { + + struct modrm_byte * modrm = (struct modrm_byte*)modrm_instr; + addr_t base_addr = 0; + modrm_addr_type_t mod_type = 0; + + PrintDebug("ModRM mod=%d\n", modrm->mod); + + if (modrm->mod == 3) { + mod_type = REG; + + PrintDebug("first operand = Register (RM=%d)\n",modrm->rm); + + switch (modrm->rm) { + case 0: + PrintDebug("EAX Operand\n"); + *first_operand = (addr_t)&(gprs->rax); + break; + case 1: + *first_operand = (addr_t)&(gprs->rcx); + break; + case 2: + *first_operand = (addr_t)&(gprs->rdx); + break; + case 3: + *first_operand = (addr_t)&(gprs->rbx); + break; + case 4: + if (reg_size == REG8) { + *first_operand = (addr_t)(&(gprs->rax) + 1); + } else { + *first_operand = (addr_t)&(gprs->rsp); + } + break; + case 5: + if (reg_size == REG8) { + *first_operand = (addr_t)(&(gprs->rcx) + 1); + } else { + *first_operand = (addr_t)&(gprs->rbp); + } + break; + case 6: + if (reg_size == REG8) { + *first_operand = (addr_t)(&(gprs->rdx) + 1); + } else { + *first_operand = (addr_t)&(gprs->rsi); + } + break; + case 7: + if (reg_size == REG8) { + *first_operand = (addr_t)(&(gprs->rbx) + 1); + } else { + *first_operand = (addr_t)&(gprs->rdi); + } + break; + } + + } else { + if (modrm->mod == 0) { + mod_type = DISP0; + } else if (modrm->mod == 1) { + mod_type = DISP8; + } else if (modrm->mod == 2) { + mod_type = DISP16; + } + + switch (modrm->rm) { + case 0: + base_addr = gprs->rbx + gprs->rsi; + case 1: + base_addr = gprs->rbx + gprs->rdi; + case 2: + base_addr = gprs->rbp + gprs->rsi; + case 3: + base_addr = gprs->rbp + gprs->rdi; + case 4: + base_addr = gprs->rsi; + case 5: + base_addr = gprs->rdi; + case 6: + if (modrm->mod == 0) { + base_addr = 0; + mod_type = DISP16; + } else { + base_addr = gprs->rbp; + } + case 7: + base_addr = gprs->rbx; + } + + if (mod_type == DISP8) { + base_addr += (uchar_t)*(modrm_instr + 1); + } else if (mod_type == DISP16) { + base_addr += (ushort_t)*(modrm_instr + 1); + } + + + *first_operand = base_addr; + } + + + + switch (modrm->reg) { + case 0: + *second_operand = (addr_t)&(gprs->rax); + break; + case 1: + *second_operand = (addr_t)&(gprs->rcx); + break; + case 2: + *second_operand = (addr_t)&(gprs->rdx); + break; + case 3: + *second_operand = (addr_t)&(gprs->rbx); + break; + case 4: + if (reg_size == REG8) { + *second_operand = (addr_t)&(gprs->rax) + 1; + } else { + *second_operand = (addr_t)&(gprs->rsp); + } + break; + case 5: + if (reg_size == REG8) { + *second_operand = (addr_t)&(gprs->rcx) + 1; + } else { + *second_operand = (addr_t)&(gprs->rbp); + } + break; + case 6: + if (reg_size == REG8) { + *second_operand = (addr_t)&(gprs->rdx) + 1; + } else { + *second_operand = (addr_t)&(gprs->rsi); + } + break; + case 7: + if (reg_size == REG8) { + *second_operand = (addr_t)&(gprs->rbx) + 1; + } else { + *second_operand = (addr_t)&(gprs->rdi); + } + break; + } + + return 0; + +} diff --git a/palacios/include/geekos/vmm_paging.h b/palacios/include/geekos/vmm_paging.h index 7a0ef4e..ec08fd5 100644 --- a/palacios/include/geekos/vmm_paging.h +++ b/palacios/include/geekos/vmm_paging.h @@ -225,8 +225,7 @@ int pte32_lookup(pte32_t * pte, addr_t addr, addr_t * entry); - -#include +struct guest_info; pde32_t * create_passthrough_pde32_pts(struct guest_info * guest_info); diff --git a/palacios/include/geekos/vmm_shadow_paging.h b/palacios/include/geekos/vmm_shadow_paging.h index cbda937..e84f72f 100644 --- a/palacios/include/geekos/vmm_shadow_paging.h +++ b/palacios/include/geekos/vmm_shadow_paging.h @@ -2,11 +2,13 @@ #define __VMM_SHADOW_PAGING_H -#include #include + +#include + struct shadow_page_state { // these two reflect the top-level page directory @@ -30,11 +32,9 @@ struct shadow_page_state { - - -#include struct guest_info; + int init_shadow_page_state(struct shadow_page_state * state); // This function will cause the shadow page table to be deleted diff --git a/palacios/src/geekos/main.c b/palacios/src/geekos/main.c index 575aa70..4f21335 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.25 $ + * $Revision: 1.26 $ * * This is free software. You are permitted to use, * redistribute, and modify it as specified in the file "COPYING". @@ -329,7 +329,7 @@ void Main(struct Boot_Info* bootInfo) vm_info.rip = rip; rsp = (addr_t)Alloc_Page(); - vm_info.rsp = (rsp +4092 );// - 0x2000; + vm_info.vm_regs.rsp = (rsp +4092 );// - 0x2000; } else { @@ -348,10 +348,10 @@ void Main(struct Boot_Info* bootInfo) vm_info.cs.limit=0xffff; */ vm_info.rip = 0xfff0; - vm_info.rsp = 0x0; + vm_info.vm_regs.rsp = 0x0; } - PrintBoth("Initializing Guest (eip=0x%.8x) (esp=0x%.8x)\n", (uint_t)vm_info.rip,(uint_t)vm_info.rsp); + PrintBoth("Initializing Guest (eip=0x%.8x) (esp=0x%.8x)\n", (uint_t)vm_info.rip,(uint_t)vm_info.vm_regs.rsp); (vmm_ops).init_guest(&vm_info); PrintBoth("Starting Guest\n"); (vmm_ops).start_guest(&vm_info); diff --git a/palacios/src/geekos/svm.c b/palacios/src/geekos/svm.c index 18ddcb5..ad870ff 100644 --- a/palacios/src/geekos/svm.c +++ b/palacios/src/geekos/svm.c @@ -116,14 +116,17 @@ int init_svm_guest(struct guest_info *info) { PrintDebug("Initializing VMCB (addr=%x)\n", info->vmm_data); Init_VMCB((vmcb_t*)(info->vmm_data), *info); - - info->vm_regs.rbx = 0; - info->vm_regs.rcx = 0; - info->vm_regs.rdx = 0; - info->vm_regs.rsi = 0; + info->rip = 0; + info->vm_regs.rdi = 0; + info->vm_regs.rsi = 0; info->vm_regs.rbp = 0; - + info->vm_regs.rsp = 0; + info->vm_regs.rbx = 0; + info->vm_regs.rdx = 0; + info->vm_regs.rcx = 0; + info->vm_regs.rax = 0; + return 0; } @@ -137,12 +140,13 @@ int start_svm_guest(struct guest_info *info) { //PrintDebugVMCB((vmcb_t*)(info->vmm_data)); while (1) { - + PrintDebug("SVM Launch Args (vmcb=%x), (info=%x), (vm_regs=%x)\n", info->vmm_data, &(info->vm_regs)); safe_svm_launch((vmcb_t*)(info->vmm_data), &(info->vm_regs)); //launch_svm((vmcb_t*)(info->vmm_data)); PrintDebug("SVM Returned\n"); if (handle_svm_exit(info) != 0) { + // handle exit code.... break; } } @@ -167,7 +171,7 @@ void Init_VMCB_Real(vmcb_t * vmcb, struct guest_info vm_info) { uint_t i; - guest_state->rsp = vm_info.rsp; + guest_state->rsp = vm_info.vm_regs.rsp; guest_state->rip = vm_info.rip; @@ -313,7 +317,7 @@ void Init_VMCB(vmcb_t * vmcb, struct guest_info vm_info) { uint_t i; - guest_state->rsp = vm_info.rsp; + guest_state->rsp = vm_info.vm_regs.rsp; guest_state->rip = vm_info.rip; @@ -433,7 +437,7 @@ void Init_VMCB_pe(vmcb_t *vmcb, struct guest_info vm_info) { uint_t i = 0; - guest_state->rsp = vm_info.rsp; + guest_state->rsp = vm_info.vm_regs.rsp; guest_state->rip = vm_info.rip; diff --git a/palacios/src/geekos/svm_ctrl_regs.c b/palacios/src/geekos/svm_ctrl_regs.c index 656bb9e..a0c5e1a 100644 --- a/palacios/src/geekos/svm_ctrl_regs.c +++ b/palacios/src/geekos/svm_ctrl_regs.c @@ -3,10 +3,10 @@ #include #include #include - +#include int handle_cr0_write(struct guest_info * info, ullong_t * new_cr0) { - vmcb_ctrl_t * ctrl_area = GET_VMCB_CTRL_AREA((vmcb_t *)(info->vmm_data)); + //vmcb_ctrl_t * ctrl_area = GET_VMCB_CTRL_AREA((vmcb_t *)(info->vmm_data)); vmcb_saved_state_t * guest_state = GET_VMCB_SAVE_STATE_AREA((vmcb_t*)(info->vmm_data)); char instr[15]; @@ -18,13 +18,33 @@ int handle_cr0_write(struct guest_info * info, ullong_t * new_cr0) { int index = 0; while (is_prefix_byte(instr[index])) { + PrintDebug("instr(%d): 0x%x\n", index, instr[index]); index++; } - + PrintDebug("instr(%d): 0x%x\n", index, instr[index]); + PrintDebug("instr(%d): 0x%x\n", index+1, instr[index + 1]); + if ((instr[index] == cr_access_byte) && - (instr[index + 1] == lmsw_byte)) { + (instr[index + 1] == lmsw_byte) && + (MODRM_REG(instr[index + 2]) == lmsw_reg_byte)) { + + addr_t first_operand; + addr_t second_operand; + // LMSW // decode mod/RM + index += 2; + + + if (decode_operands16(&(info->vm_regs), instr + index, &first_operand, &second_operand, REG16) != 0) { + // error... don't know what to do + return -1; + } + + PrintDebug("FirstOperand addr: %x, RAX addr: %x\n", first_operand, &(info->vm_regs.rax)); + + + } else if ((instr[index] == cr_access_byte) && (instr[index + 1] == clts_byte)) { diff --git a/palacios/src/geekos/svm_handler.c b/palacios/src/geekos/svm_handler.c index e5ec493..6624da6 100644 --- a/palacios/src/geekos/svm_handler.c +++ b/palacios/src/geekos/svm_handler.c @@ -2,6 +2,8 @@ #include #include +extern struct vmm_os_hooks * os_hooks; + int handle_svm_exit(struct guest_info * info) { vmcb_ctrl_t * guest_ctrl = 0; @@ -14,17 +16,19 @@ int handle_svm_exit(struct guest_info * info) { // Update the high level state info->rip = guest_state->rip; - info->rsp = guest_state->rsp; + info->vm_regs.rsp = guest_state->rsp; + info->vm_regs.rax = guest_state->rax; + info->vm_regs.rsp = guest_state->rsp; - PrintDebug("SVM Returned: (Exit Code=%x) (VMCB=%x)\n",&(guest_ctrl->exit_code), info->vmm_data); + PrintDebug("SVM Returned: (Exit Code=%x) (VMCB=%x)\n", &(guest_ctrl->exit_code), info->vmm_data); PrintDebug("RIP: %x\n", guest_state->rip); exit_code = guest_ctrl->exit_code; - // PrintDebugVMCB((vmcb_t*)(info->vmm_data)); + // PrintDebugVMCB((vmcb_t*)(info->vmm_data)); PrintDebug("SVM Returned: Exit Code: %x\n",exit_code); PrintDebug("io_info1 low = 0x%.8x\n", *(uint_t*)&(guest_ctrl->exit_info1)); PrintDebug("io_info1 high = 0x%.8x\n", *(uint_t *)(((uchar_t *)&(guest_ctrl->exit_info1)) + 4)); @@ -53,8 +57,9 @@ int handle_svm_exit(struct guest_info * info) { // Update the low level state + guest_state->rax = info->vm_regs.rax; guest_state->rip = info->rip; - guest_state->rsp = info->rsp; + guest_state->rsp = info->vm_regs.rsp; return 0; } diff --git a/palacios/src/geekos/svm_lowlevel.asm b/palacios/src/geekos/svm_lowlevel.asm index 7aa128f..3b100d3 100644 --- a/palacios/src/geekos/svm_lowlevel.asm +++ b/palacios/src/geekos/svm_lowlevel.asm @@ -7,6 +7,8 @@ %include "defs.asm" %include "symbol.asm" +SVM_ERROR equ 0xFFFFFFFF +SVM_SUCCESS equ 0x00000000 EXPORT DisableInts @@ -22,6 +24,8 @@ EXPORT launch_svm EXPORT safe_svm_launch + + ;; These need to be kept similar with the svm return values in svm.h SVM_HANDLER_SUCCESS equ 0x00 SVM_HANDLER_ERROR equ 0x1 @@ -32,22 +36,37 @@ SVM_HANDLER_HALT equ 0x2 ; Save and restore registers needed by SVM %macro Save_SVM_Registers 1 - mov [%1], ebx - mov [%1 + 8], ecx - mov [%1 + 16], edx - mov [%1 + 24], esi - mov [%1 + 32], edi - mov [%1 + 40], ebp + push eax + mov eax, dword %1 + mov [eax], edi + mov [eax + 8], esi + mov [eax + 16], ebp + mov [eax + 24], dword 0 ;; esp + mov [eax + 32], ebx + mov [eax + 40], edx + mov [eax + 48], ecx + + push ebx + mov ebx, [esp + 4] + mov [eax + 56], ebx ;; eax + pop ebx + + pop eax %endmacro %macro Restore_SVM_Registers 1 - mov ebx, [%1] - mov ecx, [%1 + 8] - mov edx, [%1 + 16] - mov esi, [%1 + 24] - mov edi, [%1 + 32] - mov ebp, [%1 + 40] + push eax + mov eax, dword %1 + mov edi, [eax] + mov esi, [eax + 8] + mov ebp, [eax + 16] +;; mov esp, [eax + 24] + mov ebx, [eax + 32] + mov edx, [eax + 40] + mov ecx, [eax + 48] +;; mov eax, [eax + 56] + pop eax %endmacro %macro vmrun 0 @@ -146,59 +165,33 @@ safe_svm_launch: push ebp mov ebp, esp pushf - pusha ;; Save Host state + pusha ;; Save Host state - push dword [ebp + 12] ;; pointer to the guest GPR save area - push dword [ebp + 8] ;; pointer to the VMCB pointer + push dword [ebp + 12] ;; pointer to the guest GPR save area + push dword [ebp + 8] ;; pointer to the VMCB pointer - mov eax, [esp + 4] ;; mov guest GPR pointer to eax +;; mov eax, [esp + 4] ;; mov guest GPR pointer to eax - Restore_SVM_Registers eax ;; Restore Guest GPR state - pop eax ;; pop VMCB pointer into eax + Restore_SVM_Registers [esp + 4] ;; Restore Guest GPR state + pop eax ;; pop VMCB pointer into eax vmload vmrun vmsave - pop eax ;; pop Guest GPR pointer into eax - Save_SVM_Registers eax ;; save guest GPRs - - popa ;; Restore Host state +;; pop eax ;; pop Guest GPR pointer into eax + Save_SVM_Registers [esp] ;; save guest GPRs + + add esp, 4 ;; skip past the gpr ptr + + popa ;; Restore Host state popf pop ebp ret -;;align 8 -;;safe_svm_launch: -;; push ebp -;; mov ebp, esp -;; pushf -;; pusha -;; -;.vmm_loop: -; mov eax, [ebp + 8] -; vmrun -; Save_SVM_Registers -; -; call handle_svm_exit -; -; mov [ebp + 12], eax -; -; and eax, eax -; -; Restore_SVM_Registers -; -; jz .vmm_loop -; -; popa -; popf -; pop ebp -; ret - - %endif diff --git a/palacios/src/geekos/vm_guest_mem.c b/palacios/src/geekos/vm_guest_mem.c index 2978ae7..98ed0c3 100644 --- a/palacios/src/geekos/vm_guest_mem.c +++ b/palacios/src/geekos/vm_guest_mem.c @@ -280,6 +280,7 @@ int host_va_to_guest_va(struct guest_info * guest_info, addr_t host_va, addr_t * */ int read_guest_va_memory(struct guest_info * guest_info, addr_t guest_va, int count, char * dest) { addr_t cursor = guest_va; + int bytes_read = 0; while (count > 0) { int dist_to_pg_edge = (PAGE_OFFSET(cursor) + PAGE_SIZE) - cursor; @@ -290,8 +291,9 @@ int read_guest_va_memory(struct guest_info * guest_info, addr_t guest_va, int co return -1; } - memcpy(dest, (void*)cursor, bytes_to_copy); - + memcpy(dest + bytes_read, (void*)host_addr, bytes_to_copy); + + bytes_read += bytes_to_copy; count -= bytes_to_copy; cursor += bytes_to_copy; } @@ -309,6 +311,7 @@ int read_guest_va_memory(struct guest_info * guest_info, addr_t guest_va, int co */ int read_guest_pa_memory(struct guest_info * guest_info, addr_t guest_pa, int count, char * dest) { addr_t cursor = guest_pa; + int bytes_read = 0; while (count > 0) { int dist_to_pg_edge = (PAGE_OFFSET(cursor) + PAGE_SIZE) - cursor; @@ -319,8 +322,38 @@ int read_guest_pa_memory(struct guest_info * guest_info, addr_t guest_pa, int co return -1; } - memcpy(dest, (void*)cursor, bytes_to_copy); + memcpy(dest + bytes_read, (void*)host_addr, bytes_to_copy); + + bytes_read += bytes_to_copy; + count -= bytes_to_copy; + cursor += bytes_to_copy; + } + + return 0; +} + + + +/* This is a straight address conversion + copy, + * except for the tiny little issue of crossing page boundries..... + */ +int write_guest_pa_memory(struct guest_info * guest_info, addr_t guest_pa, int count, char * src) { + addr_t cursor = guest_pa; + int bytes_written = 0; + + while (count > 0) { + int dist_to_pg_edge = (PAGE_OFFSET(cursor) + PAGE_SIZE) - cursor; + int bytes_to_copy = (dist_to_pg_edge > count) ? count : dist_to_pg_edge; + addr_t host_addr; + + if (guest_pa_to_host_va(guest_info, cursor, &host_addr) != 0) { + return -1; + } + + memcpy((void*)host_addr, src + bytes_written, bytes_to_copy); + + bytes_written += bytes_to_copy; count -= bytes_to_copy; cursor += bytes_to_copy; } diff --git a/palacios/src/geekos/vmm_shadow_paging.c b/palacios/src/geekos/vmm_shadow_paging.c index 3de10c7..b81b0e9 100644 --- a/palacios/src/geekos/vmm_shadow_paging.c +++ b/palacios/src/geekos/vmm_shadow_paging.c @@ -31,7 +31,10 @@ int wholesale_update_shadow_page_state(struct guest_info * guest_info) { } shadow_pde = (pde32_t *)(CR3_TO_PDE32(state->shadow_cr3.e_reg.low)); - guest_pde = (pde32_t *)(host_pa_to_host_va((void*)CR3_TO_PDE32(state->guest_cr3.e_reg.low))); + + if (host_pa_to_host_va(CR3_TO_PDE32(state->guest_cr3.e_reg.low), (addr_t*)&guest_pde) != 0) { + return -1; + } // Delete the current page table delete_page_tables_pde32(shadow_pde);