X-Git-Url: http://v3vee.org/palacios/gitweb/gitweb.cgi?a=blobdiff_plain;f=palacios%2Fsrc%2Fpalacios%2Fvmm_symcall.c;h=3d64c1f4dd05ced70b76b846a9e59d284b0e039e;hb=4d1d8fadad33de7d3ebce2083d9782048f78b44e;hp=c78fe88645ab39dfe387107cf9ebab4e5a4f059f;hpb=ee1279646a778613b23a42350b903ebb57c068f8;p=palacios.git diff --git a/palacios/src/palacios/vmm_symcall.c b/palacios/src/palacios/vmm_symcall.c index c78fe88..3d64c1f 100644 --- a/palacios/src/palacios/vmm_symcall.c +++ b/palacios/src/palacios/vmm_symcall.c @@ -18,9 +18,12 @@ */ #include +#include #include #include #include +#include +#include // A succesfull symcall returns via the RET_HCALL, with the return values in registers // A symcall error returns via the ERR_HCALL with the error code in rbx @@ -88,7 +91,7 @@ static int symcall_msr_write(struct guest_info * core, uint_t msr, struct v3_msr state->sym_call_fs = src.value; break; default: - PrintError("Invalid Symbiotic MSR write (0x%x)\n", msr); + PrintError(core->vm_info, core, "Invalid Symbiotic MSR write (0x%x)\n", msr); return -1; } return 0; @@ -123,7 +126,7 @@ int v3_init_symcall_vm(struct v3_vm_info * vm) { static int sym_call_err(struct guest_info * core, uint_t hcall_id, void * private_data) { struct v3_symcall_state * state = (struct v3_symcall_state *)&(core->sym_core_state.symcall_state); - PrintError("sym call error\n"); + PrintError(core->vm_info, core, "sym call error\n"); state->sym_call_errno = (int)core->vm_regs.rbx; v3_print_guest_state(core); @@ -139,7 +142,7 @@ static int sym_call_err(struct guest_info * core, uint_t hcall_id, void * privat static int sym_call_ret(struct guest_info * core, uint_t hcall_id, void * private_data) { struct v3_symcall_state * state = (struct v3_symcall_state *)&(core->sym_core_state.symcall_state); - // PrintError("Return from sym call (ID=%x)\n", hcall_id); + // PrintError(info->vm_info, info, "Return from sym call (ID=%x)\n", hcall_id); // v3_print_guest_state(info); state->sym_call_returned = 1; @@ -152,7 +155,7 @@ static int execute_symcall(struct guest_info * core) { while (state->sym_call_returned == 0) { if (v3_vm_enter(core) == -1) { - PrintError("Error in Sym call\n"); + PrintError(core->vm_info, core, "Error in Sym call\n"); return -1; } } @@ -161,6 +164,64 @@ static int execute_symcall(struct guest_info * core) { } +// +// We don't handle those fancy 64 bit system segments... +// +static int translate_segment(struct guest_info * info, uint16_t selector, struct v3_segment * seg) { + struct v3_segment * gdt = &(info->segments.gdtr); + addr_t gdt_addr = 0; + uint16_t seg_offset = (selector & ~0x7); + addr_t seg_addr = 0; + struct gen_segment * gen_seg = NULL; + struct seg_selector sel; + + memset(seg, 0, sizeof(struct v3_segment)); + + sel.value = selector; + + if (sel.ti == 1) { + PrintError(info->vm_info, info, "LDT translations not supported\n"); + return -1; + } + + if (v3_gva_to_hva(info, gdt->base, &gdt_addr) == -1) { + PrintError(info->vm_info, info, "Unable to translate GDT address\n"); + return -1; + } + + seg_addr = gdt_addr + seg_offset; + gen_seg = (struct gen_segment *)seg_addr; + + //translate + seg->selector = selector; + + seg->limit = gen_seg->limit_hi; + seg->limit <<= 16; + seg->limit += gen_seg->limit_lo; + + seg->base = gen_seg->base_hi; + seg->base <<= 24; + seg->base += gen_seg->base_lo; + + if (gen_seg->granularity == 1) { + seg->limit <<= 12; + seg->limit |= 0xfff; + } + + seg->type = gen_seg->type; + seg->system = gen_seg->system; + seg->dpl = gen_seg->dpl; + seg->present = gen_seg->present; + seg->avail = gen_seg->avail; + seg->long_mode = gen_seg->long_mode; + seg->db = gen_seg->db; + seg->granularity = gen_seg->granularity; + + return 0; +} + + + int v3_sym_call(struct guest_info * core, uint64_t call_num, sym_arg_t * arg0, sym_arg_t * arg1, sym_arg_t * arg2, @@ -172,7 +233,7 @@ int v3_sym_call(struct guest_info * core, struct v3_segment sym_ss; uint64_t trash_args[5] = { [0 ... 4] = 0 }; - // PrintDebug("Making Sym call\n"); + // PrintDebug(core->vm_info, core, "Making Sym call\n"); // v3_print_guest_state(info); if ((symspy_state->local_page->sym_call_enabled == 0) || @@ -200,10 +261,10 @@ int v3_sym_call(struct guest_info * core, core->rip = state->sym_call_rip; core->vm_regs.rsp = state->sym_call_rsp; // old contest rsp is saved in vm_regs - v3_translate_segment(core, state->sym_call_cs, &sym_cs); + translate_segment(core, state->sym_call_cs, &sym_cs); memcpy(&(core->segments.cs), &sym_cs, sizeof(struct v3_segment)); - v3_translate_segment(core, state->sym_call_cs + 8, &sym_ss); + translate_segment(core, state->sym_call_cs + 8, &sym_ss); memcpy(&(core->segments.ss), &sym_ss, sizeof(struct v3_segment)); core->segments.gs.base = state->sym_call_gs; @@ -221,12 +282,12 @@ int v3_sym_call(struct guest_info * core, state->sym_call_active = 1; state->sym_call_returned = 0; - // PrintDebug("Sym state\n"); + // PrintDebug(core->vm_info, core, "Sym state\n"); // v3_print_guest_state(core); // Do the sym call entry if (execute_symcall(core) == -1) { - PrintError("SYMCALL error\n"); + PrintError(core->vm_info, core, "SYMCALL error\n"); return -1; } @@ -251,7 +312,7 @@ int v3_sym_call(struct guest_info * core, - // PrintError("restoring guest state\n"); + // PrintError(core->vm_info, core, "restoring guest state\n"); // v3_print_guest_state(core); return 0;