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.


Cleanup and sanity-checking of before/after null-check and copy+paste errors (Coverit...
[palacios.git] / palacios / src / palacios / vmm_symcall.c
index c78fe88..3d64c1f 100644 (file)
  */
 
 #include <palacios/vm_guest.h>
+#include <palacios/vm_guest_mem.h>
 #include <palacios/vmm_symcall.h>
 #include <palacios/vmm_symspy.h>
 #include <palacios/vmm_msr.h>
+#include <palacios/vmm_lowlevel.h>
+#include <palacios/vmm_debug.h>
 
 // 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;