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.


More debugging output (APIC, LDT, etc)
Maciek Swiech [Thu, 9 Oct 2014 22:44:30 +0000 (17:44 -0500)]
- APIC state can now be dumped
- LDT is included
- LDT/GDT/IDT/TSS can now be dumped via v3_debug

palacios/include/palacios/vmm_debug.h
palacios/src/devices/apic.c
palacios/src/palacios/vmm_debug.c

index c325085..7328149 100644 (file)
@@ -29,6 +29,7 @@
 
 #define NUM_IDT_ENTRIES 256
 #define NUM_GDT_ENTRIES 16
+#define NUM_LDT_ENTRIES 16
 
 struct segment_selector {
     uint8_t  rpl        :  2;
@@ -212,6 +213,25 @@ struct selector_error_code {
     uint16_t ign        : 16;
 }__attribute__((packed));
 
+struct tss_long {
+    uint32_t res1;
+    uint64_t rsp0;
+    uint64_t rsp1;
+    uint64_t rsp2;
+    uint64_t res2;
+    uint64_t ist1;
+    uint64_t ist2;
+    uint64_t ist3;
+    uint64_t ist4;
+    uint64_t ist5;
+    uint64_t ist6;
+    uint64_t ist7;
+    uint64_t res3;
+    uint32_t res4;
+    uint32_t iomap_base;
+    // Followed by up to 8 KB of io permission bitmap
+} __attribute__((packed));
+
 
 int v3_init_vm_debugging(struct v3_vm_info * vm);
 
@@ -228,6 +248,8 @@ void v3_print_guest_state_all(struct v3_vm_info * vm);
 
 void v3_print_idt(struct guest_info * core, addr_t idtr_base);
 void v3_print_gdt(struct guest_info * core, addr_t gdtr_base);
+void v3_print_ldt(struct guest_info * core, addr_t ldtr_base);
+void v3_print_tss(struct guest_info * core, addr_t ldtr_base);
 void v3_print_gp_error(struct guest_info * core, addr_t exit_info1);
 
 #endif // !__V3VEE__
index 0761d6b..be7df88 100644 (file)
@@ -275,6 +275,8 @@ struct apic_dev_state {
 
 
 
+static void dump_all_apic_state(struct v3_vm_info *vm, struct apic_dev_state *a);
+static void dump_apic_state(struct guest_info *core, struct apic_state * a) ;
 
 
 static int apic_read(struct guest_info * core, addr_t guest_addr, void * dst, uint_t length, void * priv_data);
@@ -395,8 +397,12 @@ static int write_apic_msr(struct guest_info * core, uint_t msr, v3_msr_t src, vo
 
     apic->base_addr_msr.value = src.value;
 
+    // unhook from old location
+    v3_unhook_mem(core->vm_info,core->vcpu_id,apic->base_addr);
+
     apic->base_addr = src.value & ~0xfffULL;
 
+    // hook to new location
     if (v3_hook_full_mem(core->vm_info, core->vcpu_id, apic->base_addr, 
                         apic->base_addr + PAGE_SIZE_4KB, 
                         apic_read, apic_write, apic_dev) == -1) {
@@ -1886,7 +1892,7 @@ static int apic_free(struct apic_dev_state * apic_dev) {
 
        v3_lock_deinit(&(apic->irq_queue.lock));
 
-       // unhook memory
+       v3_unhook_mem(vm,core->vcpu_id,apic->base_addr);
 
     }
 
@@ -2163,6 +2169,7 @@ static int apic_init(struct v3_vm_info * vm, v3_cfg_tree_t * cfg) {
            return -1;
        }
 
+       // hook to initial location
        v3_hook_full_mem(vm, core->vcpu_id, apic->base_addr, apic->base_addr + PAGE_SIZE_4KB, apic_read, apic_write, apic_dev);
 
        PrintDebug(vm, VCORE_NONE, "apic %u: (setup device): done, my id is %u\n", i, apic->lapic_id.val);
@@ -2184,6 +2191,283 @@ static int apic_init(struct v3_vm_info * vm, v3_cfg_tree_t * cfg) {
     return 0;
 }
 
+static char hexify_nybble(char c)
+{
+    if (c>=0 && c<=9) { 
+       return '0'+c;
+    } else if (c>=0xa && c<=0xf) { 
+       return 'a'+(c-0xa);
+    } else {
+       return -1;
+    }
+}
+
+
+static int hexify_byte(char *c, char b)
+{
+    char n;
+    n = hexify_nybble( (b >> 4) & 0xf);
+    if (n==-1) { 
+       return -1;
+    }
+    c[0] = n;
+    n = hexify_nybble( b & 0xf);
+    if (n==-1) { 
+       return -1;
+    }
+    c[1] = n;
+    return 0;
+}
+
+// dest must be of length at least 2*n+1
+static int hexify_byte_string(char *dest, char *src, int n)
+{
+    int i;
+    for (i=0;i<n;i++) { 
+       if (hexify_byte(dest,src[i])) { 
+           return -1;
+       }
+       dest+=2;
+    }
+    *dest=0;
+    return 0;
+}
+
+
+static __attribute__((unused)) void dump_all_apic_state(struct v3_vm_info *vm, struct apic_dev_state *a)
+{
+    int i;
+    for (i=0;i<a->num_apics;i++) { 
+       dump_apic_state(&(vm->cores[i]),&(a->apics[i]));
+    }
+}
+       
+static void dump_apic_state(struct guest_info *core, struct apic_state * a) 
+{
+    char buf[80];
+    struct irq_queue_entry *ie;
+
+    V3_Print(core->vm_info, core, "APIC (vcore %d) {\n", core->vcpu_id);
+    V3_Print(core->vm_info, core, "\tbase_addr: %llx\n", (uint64_t)(a->base_addr));
+    V3_Print(core->vm_info, core, "\tlapic_id_reg {\n");
+    V3_Print(core->vm_info, core, "\t\trsvd: 0x%x\n", a->lapic_id.rsvd);
+    V3_Print(core->vm_info, core, "\t\tapic_id: 0x%x\n", a->lapic_id.apic_id);
+    V3_Print(core->vm_info, core, "\t}\n");
+    V3_Print(core->vm_info, core, "\tapic_ver_reg {\n");
+    V3_Print(core->vm_info, core, "\t\tver: 0x%x\n", a->apic_ver.ver);
+    V3_Print(core->vm_info, core, "\t\trsvd1: 0x%x\n", a->apic_ver.rsvd1);
+    V3_Print(core->vm_info, core, "\t\tmax_lvts: 0x%x\n", a->apic_ver.max_lvts);
+    V3_Print(core->vm_info, core, "\t\trsvd2: 0x%x\n", a->apic_ver.rsvd2);
+    V3_Print(core->vm_info, core, "\t\text_reg_present: 0x%x\n", a->apic_ver.ext_reg_present);
+    V3_Print(core->vm_info, core, "\t}\n");
+    V3_Print(core->vm_info, core, "\text_apic_ctrl_reg {\n");
+    V3_Print(core->vm_info, core, "\t\tver: 0x%x\n", a->ext_apic_ctrl.ver);
+    V3_Print(core->vm_info, core, "\t\tseoi_enable: 0x%x\n", a->ext_apic_ctrl.seoi_enable);
+    V3_Print(core->vm_info, core, "\t\text_id_enable: 0x%x\n", a->ext_apic_ctrl.ext_id_enable);
+    V3_Print(core->vm_info, core, "\t\trsvd2: 0x%x\n", a->ext_apic_ctrl.rsvd2);
+    V3_Print(core->vm_info, core, "\t}\n");
+    V3_Print(core->vm_info, core, "\tlocal_vec_tbl_reg {\n");
+    V3_Print(core->vm_info, core, "\t\tvec: 0x%x\n", a->local_vec_tbl.vec);
+    V3_Print(core->vm_info, core, "\t\tmsg_type: 0x%x\n", a->local_vec_tbl.msg_type);
+    V3_Print(core->vm_info, core, "\t\trsvd1: 0x%x\n", a->local_vec_tbl.rsvd1);
+    V3_Print(core->vm_info, core, "\t\tdel_status: 0x%x\n", a->local_vec_tbl.del_status);
+    V3_Print(core->vm_info, core, "\t\trsvd2: 0x%x\n", a->local_vec_tbl.rsvd2);
+    V3_Print(core->vm_info, core, "\t\trem_irr: 0x%x\n", a->local_vec_tbl.rem_irr);
+    V3_Print(core->vm_info, core, "\t\ttrig_mode: 0x%x\n", a->local_vec_tbl.trig_mode);
+    V3_Print(core->vm_info, core, "\t\tmask: 0x%x\n", a->local_vec_tbl.mask);
+    V3_Print(core->vm_info, core, "\t\ttmr_mode: 0x%x\n", a->local_vec_tbl.tmr_mode);
+    V3_Print(core->vm_info, core, "\t\trsvd3: 0x%x\n", a->local_vec_tbl.rsvd3);
+    V3_Print(core->vm_info, core, "\t}\n");
+    V3_Print(core->vm_info, core, "\ttmr_vec_tbl_reg {\n");
+    V3_Print(core->vm_info, core, "\t\tvec: 0x%x\n", a->tmr_vec_tbl.vec);
+    V3_Print(core->vm_info, core, "\t\trsvd: 0x%x\n", a->tmr_vec_tbl.rsvd);
+    V3_Print(core->vm_info, core, "\t\tdel_status: 0x%x\n", a->tmr_vec_tbl.del_status);
+    V3_Print(core->vm_info, core, "\t\trsvd2: 0x%x\n", a->tmr_vec_tbl.rsvd2);
+    V3_Print(core->vm_info, core, "\t\tmask: 0x%x\n", a->tmr_vec_tbl.mask);
+    V3_Print(core->vm_info, core, "\t\ttmr_mode: 0x%x\n", a->tmr_vec_tbl.tmr_mode);
+    V3_Print(core->vm_info, core, "\t\trsvd3: 0x%x\n", a->tmr_vec_tbl.rsvd3);
+    V3_Print(core->vm_info, core, "\t}\n");
+    V3_Print(core->vm_info, core, "\ttmr_div_cfg_reg {\n");
+    V3_Print(core->vm_info, core, "\t\tdiv_val: 0x%x\n", a->tmr_div_cfg.div_val);
+    V3_Print(core->vm_info, core, "\t\trsvd1: 0x%x\n", a->tmr_div_cfg.rsvd1);
+    V3_Print(core->vm_info, core, "\t\tdiv_val2: 0x%x\n", a->tmr_div_cfg.div_val2);
+    V3_Print(core->vm_info, core, "\t\trsvd2: 0x%x\n", a->tmr_div_cfg.rsvd2);
+    V3_Print(core->vm_info, core, "\t}\n");
+    V3_Print(core->vm_info, core, "\tlint_vec_tbl_reg 0 {\n");
+    V3_Print(core->vm_info, core, "\t\tvec: 0x%x\n", a->lint0_vec_tbl.vec);
+    V3_Print(core->vm_info, core, "\t\tmsg_type: 0x%x\n", a->lint0_vec_tbl.msg_type);
+    V3_Print(core->vm_info, core, "\t\trsvd1: 0x%x\n", a->lint0_vec_tbl.rsvd1);
+    V3_Print(core->vm_info, core, "\t\tdel_status: 0x%x\n", a->lint0_vec_tbl.del_status);
+    V3_Print(core->vm_info, core, "\t\trsvd2: 0x%x\n", a->lint0_vec_tbl.rsvd2);
+    V3_Print(core->vm_info, core, "\t\trem_irr: 0x%x\n", a->lint0_vec_tbl.rem_irr);
+    V3_Print(core->vm_info, core, "\t\ttrig_mode: 0x%x\n", a->lint0_vec_tbl.trig_mode);
+    V3_Print(core->vm_info, core, "\t\tmask: 0x%x\n", a->lint0_vec_tbl.mask);
+    V3_Print(core->vm_info, core, "\t\trsvd3: 0x%x\n", a->lint0_vec_tbl.rsvd3);
+    V3_Print(core->vm_info, core, "\t}\n");
+    V3_Print(core->vm_info, core, "\tlint_vec_tbl_reg 1 {\n");
+    V3_Print(core->vm_info, core, "\t\tvec: 0x%x\n", a->lint1_vec_tbl.vec);
+    V3_Print(core->vm_info, core, "\t\tmsg_type: 0x%x\n", a->lint1_vec_tbl.msg_type);
+    V3_Print(core->vm_info, core, "\t\trsvd1: 0x%x\n", a->lint1_vec_tbl.rsvd1);
+    V3_Print(core->vm_info, core, "\t\tdel_status: 0x%x\n", a->lint1_vec_tbl.del_status);
+    V3_Print(core->vm_info, core, "\t\trsvd2: 0x%x\n", a->lint1_vec_tbl.rsvd2);
+    V3_Print(core->vm_info, core, "\t\trem_irr: 0x%x\n", a->lint1_vec_tbl.rem_irr);
+    V3_Print(core->vm_info, core, "\t\ttrig_mode: 0x%x\n", a->lint1_vec_tbl.trig_mode);
+    V3_Print(core->vm_info, core, "\t\tmask: 0x%x\n", a->lint1_vec_tbl.mask);
+    V3_Print(core->vm_info, core, "\t\trsvd3: 0x%x\n", a->lint1_vec_tbl.rsvd3);
+    V3_Print(core->vm_info, core, "\t}\n");
+    V3_Print(core->vm_info, core, "\tperf_ctr_loc_vec_tbl_reg {\n");
+    V3_Print(core->vm_info, core, "\t\tvec: 0x%x\n", a->perf_ctr_loc_vec_tbl.vec);
+    V3_Print(core->vm_info, core, "\t\tmsg_type: 0x%x\n", a->perf_ctr_loc_vec_tbl.msg_type);
+    V3_Print(core->vm_info, core, "\t\trsvd1: 0x%x\n", a->perf_ctr_loc_vec_tbl.rsvd1);
+    V3_Print(core->vm_info, core, "\t\tdel_status: 0x%x\n", a->perf_ctr_loc_vec_tbl.del_status);
+    V3_Print(core->vm_info, core, "\t\trsvd2: 0x%x\n", a->perf_ctr_loc_vec_tbl.rsvd2);
+    V3_Print(core->vm_info, core, "\t\tmask: 0x%x\n", a->perf_ctr_loc_vec_tbl.mask);
+    V3_Print(core->vm_info, core, "\t\trsvd3: 0x%x\n", a->perf_ctr_loc_vec_tbl.rsvd3);
+    V3_Print(core->vm_info, core, "\t}\n");
+    V3_Print(core->vm_info, core, "\ttherm_loc_vec_tbl_reg {\n");
+    V3_Print(core->vm_info, core, "\t\tvec: 0x%x\n", a->therm_loc_vec_tbl.vec);
+    V3_Print(core->vm_info, core, "\t\tmsg_type: 0x%x\n", a->therm_loc_vec_tbl.msg_type);
+    V3_Print(core->vm_info, core, "\t\trsvd1: 0x%x\n", a->therm_loc_vec_tbl.rsvd1);
+    V3_Print(core->vm_info, core, "\t\tdel_status: 0x%x\n", a->therm_loc_vec_tbl.del_status);
+    V3_Print(core->vm_info, core, "\t\trsvd2: 0x%x\n", a->therm_loc_vec_tbl.rsvd2);
+    V3_Print(core->vm_info, core, "\t\tmask: 0x%x\n", a->therm_loc_vec_tbl.mask);
+    V3_Print(core->vm_info, core, "\t\trsvd3: 0x%x\n", a->therm_loc_vec_tbl.rsvd3);
+    V3_Print(core->vm_info, core, "\t}\n");
+    V3_Print(core->vm_info, core, "\terr_vec_tbl_reg {\n");
+    V3_Print(core->vm_info, core, "\t\tvec: 0x%x\n", a->err_vec_tbl.vec);
+    V3_Print(core->vm_info, core, "\t\tmsg_type: 0x%x\n", a->err_vec_tbl.msg_type);
+    V3_Print(core->vm_info, core, "\t\trsvd1: 0x%x\n", a->err_vec_tbl.rsvd1);
+    V3_Print(core->vm_info, core, "\t\tdel_status: 0x%x\n", a->err_vec_tbl.del_status);
+    V3_Print(core->vm_info, core, "\t\trsvd2: 0x%x\n", a->err_vec_tbl.rsvd2);
+    V3_Print(core->vm_info, core, "\t\tmask: 0x%x\n", a->err_vec_tbl.mask);
+    V3_Print(core->vm_info, core, "\t\trsvd3: 0x%x\n", a->err_vec_tbl.rsvd3);
+    V3_Print(core->vm_info, core, "\t}\n");
+    V3_Print(core->vm_info, core, "\terr_status_reg {\n");
+    V3_Print(core->vm_info, core, "\t\trsvd1: 0x%x\n", a->err_status.rsvd1);
+    V3_Print(core->vm_info, core, "\t\tsent_acc_err: 0x%x\n", a->err_status.sent_acc_err);
+    V3_Print(core->vm_info, core, "\t\trecv_acc_err: 0x%x\n", a->err_status.recv_acc_err);
+    V3_Print(core->vm_info, core, "\t\trsvd2: 0x%x\n", a->err_status.rsvd2);
+    V3_Print(core->vm_info, core, "\t\tsent_ill_err: 0x%x\n", a->err_status.sent_ill_err);
+    V3_Print(core->vm_info, core, "\t\trecv_ill_err: 0x%x\n", a->err_status.recv_ill_err);
+    V3_Print(core->vm_info, core, "\t\till_reg_addr: 0x%x\n", a->err_status.ill_reg_addr);
+    V3_Print(core->vm_info, core, "\t\trsvd3: 0x%x\n", a->err_status.rsvd3);
+    V3_Print(core->vm_info, core, "\t}\n");
+    V3_Print(core->vm_info, core, "\tspurious_int_reg {\n");
+    V3_Print(core->vm_info, core, "\t\tvec: 0x%x\n", a->spurious_int.vec);
+    V3_Print(core->vm_info, core, "\t\tapic_soft_en: 0x%x\n", a->spurious_int.apic_soft_en);
+    V3_Print(core->vm_info, core, "\t\tfoc_cpu_chk: 0x%x\n", a->spurious_int.foc_cpu_chk);
+    V3_Print(core->vm_info, core, "\t\trsvd1: 0x%x\n", a->spurious_int.rsvd1);
+    V3_Print(core->vm_info, core, "\t}\n");
+    V3_Print(core->vm_info, core, "\tint_cmd_reg {\n");
+    V3_Print(core->vm_info, core, "\t\tvec: 0x%x\n", a->int_cmd.vec);
+    V3_Print(core->vm_info, core, "\t\tdel_mode: 0x%x\n", a->int_cmd.del_mode);
+    V3_Print(core->vm_info, core, "\t\tdst_mode: 0x%x\n", a->int_cmd.dst_mode);
+    V3_Print(core->vm_info, core, "\t\tdel_status: 0x%x\n", a->int_cmd.del_status);
+    V3_Print(core->vm_info, core, "\t\trsvd1: 0x%x\n", a->int_cmd.rsvd1);
+    V3_Print(core->vm_info, core, "\t\tlvl: 0x%x\n", a->int_cmd.lvl);
+    V3_Print(core->vm_info, core, "\t\ttrig_mode: 0x%x\n", a->int_cmd.trig_mode);
+    V3_Print(core->vm_info, core, "\t\trm_rd_status: 0x%x\n", a->int_cmd.rem_rd_status);
+    V3_Print(core->vm_info, core, "\t\tdst_shorthand: 0x%x\n", a->int_cmd.dst_shorthand);
+    V3_Print(core->vm_info, core, "\t\trsvd2: 0x%llx\n", (uint64_t)(a->int_cmd.rsvd2));
+    V3_Print(core->vm_info, core, "\t\tdst: 0x%x\n", a->int_cmd.dst);
+    V3_Print(core->vm_info, core, "\t}\n");
+    V3_Print(core->vm_info, core, "\tlog_dst_reg {\n");
+    V3_Print(core->vm_info, core, "\t\trsvd1: 0x%x\n", a->log_dst.rsvd1);
+    V3_Print(core->vm_info, core, "\t\tdst_log_id: 0x%x\n", a->log_dst.dst_log_id);
+    V3_Print(core->vm_info, core, "\t}\n");
+    V3_Print(core->vm_info, core, "\tdst_fmt_reg {\n");
+    V3_Print(core->vm_info, core, "\t\trsvd1: 0x%x\n", a->dst_fmt.rsvd1);
+    V3_Print(core->vm_info, core, "\t\tmodel: 0x%x\n", a->dst_fmt.model);
+    V3_Print(core->vm_info, core, "\t}\n");
+    V3_Print(core->vm_info, core, "\tarb_prio_reg: 0x%x\n",get_apic_apr(a));
+    V3_Print(core->vm_info, core, "\ttask_prio_reg: 0x%x\n", get_apic_tpr(a));
+    V3_Print(core->vm_info, core, "\tproc_prio_reg: 0x%x\n",get_apic_ppr(a));
+    V3_Print(core->vm_info, core, "\text_apic_feature_reg {\n");
+    V3_Print(core->vm_info, core, "\t\tint_en_reg_cap: 0x%x\n", a->ext_apic_feature.int_en_reg_cap);
+    V3_Print(core->vm_info, core, "\t\tspec_eoi_cap: 0x%x\n", a->ext_apic_feature.spec_eoi_cap);
+    V3_Print(core->vm_info, core, "\t\text_apic_id_cap: 0x%x\n", a->ext_apic_feature.ext_apic_id_cap);
+    V3_Print(core->vm_info, core, "\t\trsvd1: 0x%x\n", a->ext_apic_feature.rsvd1);
+    V3_Print(core->vm_info, core, "\t\text_lvt_cnt: 0x%x\n", a->ext_apic_feature.ext_lvt_cnt);
+    V3_Print(core->vm_info, core, "\t\trsvd2: 0x%x\n", a->ext_apic_feature.rsvd2);
+    V3_Print(core->vm_info, core, "\t}\n");
+    V3_Print(core->vm_info, core, "\tspec_eoi_reg {\n");
+    V3_Print(core->vm_info, core, "\t\tvec: 0x%x\n", a->spec_eoi.vec);
+    V3_Print(core->vm_info, core, "\t\trsvd1: 0x%x\n", a->spec_eoi.rsvd1);
+    V3_Print(core->vm_info, core, "\t}\n");
+    V3_Print(core->vm_info, core, "\ttmr_cur_cnt: 0x%x\n", a->tmr_cur_cnt);
+    V3_Print(core->vm_info, core, "\ttmr_init_cnt: 0x%x\n", a->tmr_init_cnt);
+    V3_Print(core->vm_info, core, "\tmissed_ints: 0x%x\n", a->missed_ints);
+    V3_Print(core->vm_info, core, "\text_vec_tbl_reg 0 {\n");
+    V3_Print(core->vm_info, core, "\t\tvec: 0x%x\n", a->ext_intr_vec_tbl[0].vec);
+    V3_Print(core->vm_info, core, "\t\tmsg_type: 0x%x\n", a->ext_intr_vec_tbl[0].msg_type);
+    V3_Print(core->vm_info, core, "\t\trsvd1: 0x%x\n", a->ext_intr_vec_tbl[0].rsvd1);
+    V3_Print(core->vm_info, core, "\t\tdel_status: 0x%x\n", a->ext_intr_vec_tbl[0].del_status);
+    V3_Print(core->vm_info, core, "\t\trsvd2: 0x%x\n", a->ext_intr_vec_tbl[0].rsvd2);
+    V3_Print(core->vm_info, core, "\t\trem_irr: 0x%x\n", a->ext_intr_vec_tbl[0].rem_irr);
+    V3_Print(core->vm_info, core, "\t\ttrig_mode: 0x%x\n", a->ext_intr_vec_tbl[0].trig_mode);
+    V3_Print(core->vm_info, core, "\t\tmask: 0x%x\n", a->ext_intr_vec_tbl[0].mask);
+    V3_Print(core->vm_info, core, "\t\ttmr_mode: 0x%x\n", a->ext_intr_vec_tbl[0].tmr_mode);
+    V3_Print(core->vm_info, core, "\t\trsvd3: 0x%x\n", a->ext_intr_vec_tbl[0].rsvd3);
+    V3_Print(core->vm_info, core, "\t}\n");
+    V3_Print(core->vm_info, core, "\text_vec_tbl_reg 1 {\n");
+    V3_Print(core->vm_info, core, "\t\tvec: 0x%x\n", a->ext_intr_vec_tbl[1].vec);
+    V3_Print(core->vm_info, core, "\t\tmsg_type: 0x%x\n", a->ext_intr_vec_tbl[1].msg_type);
+    V3_Print(core->vm_info, core, "\t\trsvd1: 0x%x\n", a->ext_intr_vec_tbl[1].rsvd1);
+    V3_Print(core->vm_info, core, "\t\tdel_status: 0x%x\n", a->ext_intr_vec_tbl[1].del_status);
+    V3_Print(core->vm_info, core, "\t\trsvd2: 0x%x\n", a->ext_intr_vec_tbl[1].rsvd2);
+    V3_Print(core->vm_info, core, "\t\trem_irr: 0x%x\n", a->ext_intr_vec_tbl[1].rem_irr);
+    V3_Print(core->vm_info, core, "\t\ttrig_mode: 0x%x\n", a->ext_intr_vec_tbl[1].trig_mode);
+    V3_Print(core->vm_info, core, "\t\tmask: 0x%x\n", a->ext_intr_vec_tbl[1].mask);
+    V3_Print(core->vm_info, core, "\t\ttmr_mode: 0x%x\n", a->ext_intr_vec_tbl[1].tmr_mode);
+    V3_Print(core->vm_info, core, "\t\trsvd3: 0x%x\n", a->ext_intr_vec_tbl[1].rsvd3);
+    V3_Print(core->vm_info, core, "\t}\n");
+    V3_Print(core->vm_info, core, "\text_vec_tbl_reg 2 {\n");
+    V3_Print(core->vm_info, core, "\t\tvec: 0x%x\n", a->ext_intr_vec_tbl[2].vec);
+    V3_Print(core->vm_info, core, "\t\tmsg_type: 0x%x\n", a->ext_intr_vec_tbl[2].msg_type);
+    V3_Print(core->vm_info, core, "\t\trsvd1: 0x%x\n", a->ext_intr_vec_tbl[2].rsvd1);
+    V3_Print(core->vm_info, core, "\t\tdel_status: 0x%x\n", a->ext_intr_vec_tbl[2].del_status);
+    V3_Print(core->vm_info, core, "\t\trsvd2: 0x%x\n", a->ext_intr_vec_tbl[2].rsvd2);
+    V3_Print(core->vm_info, core, "\t\trem_irr: 0x%x\n", a->ext_intr_vec_tbl[2].rem_irr);
+    V3_Print(core->vm_info, core, "\t\ttrig_mode: 0x%x\n", a->ext_intr_vec_tbl[2].trig_mode);
+    V3_Print(core->vm_info, core, "\t\tmask: 0x%x\n", a->ext_intr_vec_tbl[2].mask);
+    V3_Print(core->vm_info, core, "\t\ttmr_mode: 0x%x\n", a->ext_intr_vec_tbl[2].tmr_mode);
+    V3_Print(core->vm_info, core, "\t\trsvd3: 0x%x\n", a->ext_intr_vec_tbl[2].rsvd3);
+    V3_Print(core->vm_info, core, "\t}\n");
+    V3_Print(core->vm_info, core, "\text_vec_tbl_reg 3 {\n");
+    V3_Print(core->vm_info, core, "\t\tvec: 0x%x\n", a->ext_intr_vec_tbl[3].vec);
+    V3_Print(core->vm_info, core, "\t\tmsg_type: 0x%x\n", a->ext_intr_vec_tbl[3].msg_type);
+    V3_Print(core->vm_info, core, "\t\trsvd1: 0x%x\n", a->ext_intr_vec_tbl[3].rsvd1);
+    V3_Print(core->vm_info, core, "\t\tdel_status: 0x%x\n", a->ext_intr_vec_tbl[3].del_status);
+    V3_Print(core->vm_info, core, "\t\trsvd2: 0x%x\n", a->ext_intr_vec_tbl[3].rsvd2);
+    V3_Print(core->vm_info, core, "\t\trem_irr: 0x%x\n", a->ext_intr_vec_tbl[3].rem_irr);
+    V3_Print(core->vm_info, core, "\t\ttrig_mode: 0x%x\n", a->ext_intr_vec_tbl[3].trig_mode);
+    V3_Print(core->vm_info, core, "\t\tmask: 0x%x\n", a->ext_intr_vec_tbl[3].mask);
+    V3_Print(core->vm_info, core, "\t\ttmr_mode: 0x%x\n", a->ext_intr_vec_tbl[3].tmr_mode);
+    V3_Print(core->vm_info, core, "\t\trsvd3: 0x%x\n", a->ext_intr_vec_tbl[3].rsvd3);
+    V3_Print(core->vm_info, core, "\t}\n");
+    V3_Print(core->vm_info, core, "\trem_rd_data: 0x%x\n", a->rem_rd_data);
+    hexify_byte_string(buf,a->int_req_reg,32);
+    V3_Print(core->vm_info, core, "\tint_req_reg: 0x%s\n",buf);
+    hexify_byte_string(buf,a->int_svc_reg,32);
+    V3_Print(core->vm_info, core, "\tint_svc_reg: 0x%s\n",buf);
+    hexify_byte_string(buf,a->int_en_reg,32);
+    V3_Print(core->vm_info, core, "\tint_en_reg: 0x%s\n",buf);
+    hexify_byte_string(buf,a->trig_mode_reg,32);
+    V3_Print(core->vm_info, core, "\ttrig_mode_reg: 0x%s\n",buf);
+    V3_Print(core->vm_info, core, "\tirq_ack_cbs: SKIPPED\n");
+    V3_Print(core->vm_info, core, "\tirq_queue: (follows)\n");
+    // note we do not hold the lock for purposes of printing this list... 
+    list_for_each_entry(ie,&(a->irq_queue.entries), list_node) {
+       V3_Print(core->vm_info,core,"\t\tvector 0x%x ack %p priv %p\n", ie->vector, ie->ack, ie->private_data);
+    }
+    V3_Print(core->vm_info, core, "\t}\n");
+    V3_Print(core->vm_info, core, "\teoi: 0x%x\n", a->eoi);
+    V3_Print(core->vm_info, core,"}\n");
+}
+
+
+
+
 
 
 device_register("LAPIC", apic_init)
index 185497b..cc31a52 100644 (file)
@@ -262,6 +262,11 @@ void v3_print_guest_state(struct guest_info * core) {
     }
     v3_print_GPRs(core);
 
+    v3_print_idt(core,core->segments.idtr.base);
+    v3_print_gdt(core,core->segments.gdtr.base);
+    v3_print_ldt(core,core->segments.ldtr.base);
+    v3_print_tss(core,core->segments.tr.base);
+
     v3_print_mem_map(core->vm_info);
 
     v3_print_stack(core);
@@ -460,6 +465,13 @@ void v3_print_GPRs(struct guest_info * core) {
 void v3_print_idt(struct guest_info * core, addr_t idtr_base) {
     addr_t base_hva;
 
+    if (v3_get_vm_cpu_mode(core)!=LONG) { 
+       V3_Print(core->vm_info, core, "= IDT ========\n");
+       V3_Print(core->vm_info, core, "(currently only supported in long mode)\n");
+       return;
+    }
+       
+
     if (core->mem_mode == PHYSICAL_MEM) {
         v3_gpa_to_hva(core, 
                       get_addr_linear(core, idtr_base, &(core->segments.cs)),
@@ -482,12 +494,12 @@ void v3_print_idt(struct guest_info * core, addr_t idtr_base) {
 
     struct int_trap_gate_lgcy * entry;
     entry = (struct int_trap_gate_lgcy *)base_hva;
-    PrintDebug(core->vm_info, core, "= IDT ========\n");
-    PrintDebug(core->vm_info, core, "  # | hex | selector | si:ti:rpl |   offset | type | dpl | s | p\n");
+    V3_Print(core->vm_info, core, "= IDT ========\n");
+    V3_Print(core->vm_info, core, "  # | hex | selector | si:ti:rpl |   offset | type | dpl | s | p\n");
     for (i = 0; i < NUM_IDT_ENTRIES; i++) {
         uint32_t tmp = entry->selector;
         struct segment_selector * seg = (struct segment_selector *)(&tmp);
-        PrintDebug(core->vm_info, core, "%3d | %3x |     %04x |   %03x:%x:%x | %04x%04x | %s |   %x | %x | %x | %x\n", i, i,
+        V3_Print(core->vm_info, core, "%3d | %3x |     %04x |   %03x:%x:%x | %04x%04x | %s |   %x | %x | %x | %x\n", i, i,
                 entry->selector,
                 seg->index, seg->ti, seg->rpl,
                 entry->offset_hi, entry->offset_lo,
@@ -499,6 +511,12 @@ void v3_print_idt(struct guest_info * core, addr_t idtr_base) {
 void v3_print_gdt(struct guest_info * core, addr_t gdtr_base) {
     addr_t base_hva;
 
+    if (v3_get_vm_cpu_mode(core)!=LONG) { 
+       V3_Print(core->vm_info, core, "= GDT ========\n");
+       V3_Print(core->vm_info, core, "(currently only supported in long mode)\n");
+       return;
+    }
+
     if (core->mem_mode == PHYSICAL_MEM) {
         v3_gpa_to_hva(core, 
                       get_addr_linear(core, gdtr_base, &(core->segments.cs)),
@@ -516,15 +534,15 @@ void v3_print_gdt(struct guest_info * core, addr_t gdtr_base) {
     }
 
     int i;
-    char* cd[2] = {"code","data"};
+    char* cd[2] = {"data","code"};
     // TODO: handle possibility of gate/segment descriptor
 
     struct code_desc_lgcy * entry;
     entry = (struct code_desc_long *)base_hva;
-    PrintDebug(core->vm_info, core, "= GDT ========\n");
-    PrintDebug(core->vm_info, core, "  # | hex | limit |     base |  c/d | dpl | p\n");
+    V3_Print(core->vm_info, core, "= GDT ========\n");
+    V3_Print(core->vm_info, core, "  # | hex | limit |     base |  c/d | dpl | p\n");
     for (i = 0; i < NUM_GDT_ENTRIES; i++) {
-        PrintDebug(core->vm_info, core, "%3d | %3x | %x%04x | %02x%02x%04x | %s |   %x | %x\n", i, i,
+        V3_Print(core->vm_info, core, "%3d | %3x | %x%04x | %02x%02x%04x | %s |   %x | %x\n", i, i,
                 entry->limit_hi, entry->limit_lo,
                 entry->base_hi, entry->base_mid, entry->base_lo,
                 cd[entry->one1], entry->dpl, entry->p);
@@ -535,7 +553,7 @@ void v3_print_gdt(struct guest_info * core, addr_t gdtr_base) {
 void v3_print_gp_error(struct guest_info * core, addr_t exit_info1) {
     struct selector_error_code * error = (struct selector_error_code *)(&exit_info1);
 
-    PrintDebug(core->vm_info, core, "      selector index: %x, TI: %x, IDT: %x, EXT: %x (error=%llx)\n",
+    V3_Print(core->vm_info, core, "      selector index: %x, TI: %x, IDT: %x, EXT: %x (error=%llx)\n",
             error->index, error->ti, error->idt, error->ext,
             (unsigned long long)exit_info1);
 }
@@ -561,6 +579,12 @@ void v3_print_GPRs(struct guest_info * core) {
 void v3_print_idt(struct guest_info * core, addr_t idtr_base) {
     addr_t base_hva;
 
+    if (v3_get_vm_cpu_mode(core)!=LONG) { 
+       V3_Print(core->vm_info, core, "= IDT ========\n");
+       V3_Print(core->vm_info, core, "(currently only supported in long mode)\n");
+       return;
+    }
+
     if (core->mem_mode == PHYSICAL_MEM) {
         v3_gpa_to_hva(core, 
                       get_addr_linear(core, idtr_base, &(core->segments.cs)),
@@ -582,12 +606,12 @@ void v3_print_idt(struct guest_info * core, addr_t idtr_base) {
 
     struct int_trap_gate_long * entry;
     entry = (struct int_trap_gate_long *)base_hva;
-    PrintDebug(core->vm_info, core, "= IDT ========\n");
-    PrintDebug(core->vm_info, core, "  # | hex | selector | si:ti:rpl |           offset | type | dpl | s | r | p\n");
+    V3_Print(core->vm_info, core, "= IDT ========\n");
+    V3_Print(core->vm_info, core, "  # | hex | selector | si:ti:rpl |           offset | type | dpl | s | r | p\n");
     for (i = 0; i < NUM_IDT_ENTRIES; i++) {
         uint32_t tmp = entry->selector;
         struct segment_selector * seg = (struct segment_selector *)(&tmp);
-        PrintDebug(core->vm_info, core, "%3d | %3x |     %04x |   %03x:%x:%x | %08x%04x%04x | %s |   %x | %x | %x | %x\n", i, i,
+        V3_Print(core->vm_info, core, "%3d | %3x |     %04x |   %03x:%x:%x | %08x%04x%04x | %s |   %x | %x | %x | %x\n", i, i,
                 entry->selector,
                 seg->index, seg->ti, seg->rpl,
                 entry->offset_hi, entry->offset_mid, entry->offset_lo,
@@ -600,6 +624,12 @@ void v3_print_idt(struct guest_info * core, addr_t idtr_base) {
 void v3_print_gdt(struct guest_info * core, addr_t gdtr_base) {
     addr_t base_hva;
 
+    if (v3_get_vm_cpu_mode(core)!=LONG) { 
+       V3_Print(core->vm_info, core, "= GDT ========\n");
+       V3_Print(core->vm_info, core, "(currently only supported in long mode)\n");
+       return;
+    }
+
     if (core->mem_mode == PHYSICAL_MEM) {
         v3_gpa_to_hva(core, 
                       get_addr_linear(core, gdtr_base, &(core->segments.cs)),
@@ -616,15 +646,62 @@ void v3_print_gdt(struct guest_info * core, addr_t gdtr_base) {
     }
 
     int i;
-    char* cd[2] = {"code","data"};
+    char* cd[2] = {"data","code"};
     // TODO: handle possibility of gate/segment descriptor
 
     struct code_desc_long * entry;
     entry = (struct code_desc_long *)base_hva;
-    PrintDebug(core->vm_info, core, "= GDT ========\n");
-    PrintDebug(core->vm_info, core, "  # | hex | limit |     base |  c/d | dpl | p\n");
+    V3_Print(core->vm_info, core, "= GDT ========\n");
+    V3_Print(core->vm_info, core, "  # | hex | limit |     base |  c/d | dpl | p\n");
     for (i = 0; i < NUM_GDT_ENTRIES; i++) {
-        PrintDebug(core->vm_info, core, "%3d | %3x | %x%04x | %02x%02x%04x | %s |   %x | %x\n", i, i,
+        V3_Print(core->vm_info, core, "%3d | %3x | %x%04x | %02x%02x%04x | %s |   %x | %x\n", i, i,
+                entry->limit_hi, entry->limit_lo,
+                entry->base_hi, entry->base_mid, entry->base_lo,
+                cd[entry->one1], entry->dpl, entry->p);
+        entry++;
+    }
+}
+
+void v3_print_ldt(struct guest_info * core, addr_t ldtr_base) {
+    addr_t base_hva;
+
+    if (v3_get_vm_cpu_mode(core)!=LONG) { 
+       V3_Print(core->vm_info, core, "= LDT ========\n");
+       V3_Print(core->vm_info, core, "(currently only supported in long mode)\n");
+       return;
+    }
+
+    V3_Print(core->vm_info, core, "= LDT ========\n");
+
+    if (ldtr_base == 0) {
+        V3_Print(core->vm_info, core, "        (no LDT is installed)\n");
+       return;
+    } 
+
+    if (core->mem_mode == PHYSICAL_MEM) {
+        v3_gpa_to_hva(core, 
+                      get_addr_linear(core, ldtr_base, &(core->segments.cs)),
+                      &base_hva);
+    } else if (core->mem_mode == VIRTUAL_MEM) {
+        v3_gva_to_hva(core, 
+                      get_addr_linear(core, ldtr_base, &(core->segments.cs)),
+                      &base_hva);
+    }
+
+    // SANITY CHECK
+    if (ldtr_base != get_addr_linear(core, ldtr_base, &(core->segments.cs))) {
+        PrintError(core->vm_info, core, "ldtr base address != linear translation, might be something funky with cs\n");
+    }
+
+    int i;
+    char* cd[2] = {"data","code"};
+    // TODO: handle possibility of gate/segment descriptor
+
+    struct code_desc_long * entry;
+    entry = (struct code_desc_long *)base_hva;
+    V3_Print(core->vm_info, core, "  # | hex | limit |     base |  c/d | dpl | p\n");
+    for (i = 0; i < NUM_LDT_ENTRIES; i++) {
+        V3_Print(core->vm_info, core, "%3d | %3x | %x%04x | %02x%02x%04x | %s |   %x | %x\n", i, i,
                 entry->limit_hi, entry->limit_lo,
                 entry->base_hi, entry->base_mid, entry->base_lo,
                 cd[entry->one1], entry->dpl, entry->p);
@@ -632,10 +709,68 @@ void v3_print_gdt(struct guest_info * core, addr_t gdtr_base) {
     }
 }
 
+void v3_print_tss(struct guest_info * core, addr_t tr_base) {
+    addr_t base_hva;
+    struct tss_long *t;
+
+    if (v3_get_vm_cpu_mode(core)!=LONG) { 
+       V3_Print(core->vm_info, core, "= TSS ========\n");
+       V3_Print(core->vm_info, core, "(currently only supported in long mode)\n");
+       return;
+    }
+
+    V3_Print(core->vm_info, core, "= TSS ========\n");
+
+    if (tr_base == 0) {
+        V3_Print(core->vm_info, core, "        (no TSS is installed)\n");
+       return;
+    } 
+
+    if (core->mem_mode == PHYSICAL_MEM) {
+        v3_gpa_to_hva(core, 
+                      get_addr_linear(core, tr_base, &(core->segments.cs)),
+                      &base_hva);
+    } else if (core->mem_mode == VIRTUAL_MEM) {
+        v3_gva_to_hva(core, 
+                      get_addr_linear(core, tr_base, &(core->segments.cs)),
+                      &base_hva);
+    }
+
+    // SANITY CHECK
+    if (tr_base != get_addr_linear(core, tr_base, &(core->segments.cs))) {
+        PrintError(core->vm_info, core, "tr base address != linear translation, might be something funky with cs\n");
+    }
+    t=(struct tss_long*)base_hva;
+
+    V3_Print(core->vm_info, core," res1 : 0x%llx\n", (uint64_t) t->res1);
+    V3_Print(core->vm_info, core," rsp0 : 0x%llx\n", t->rsp0);
+    V3_Print(core->vm_info, core," rsp1 : 0x%llx\n", t->rsp1);
+    V3_Print(core->vm_info, core," rsp2 : 0x%llx\n", t->rsp2);
+    V3_Print(core->vm_info, core," res2 : 0x%llx\n", t->res2);
+    V3_Print(core->vm_info, core," ist1 : 0x%llx\n", t->ist1);
+    V3_Print(core->vm_info, core," ist2 : 0x%llx\n", t->ist2);
+    V3_Print(core->vm_info, core," ist3 : 0x%llx\n", t->ist3);
+    V3_Print(core->vm_info, core," ist4 : 0x%llx\n", t->ist4);
+    V3_Print(core->vm_info, core," ist5 : 0x%llx\n", t->ist5);
+    V3_Print(core->vm_info, core," ist6 : 0x%llx\n", t->ist6);
+    V3_Print(core->vm_info, core," ist7 : 0x%llx\n", t->ist7);
+    V3_Print(core->vm_info, core," res3 : 0x%llx\n", t->res3);
+    V3_Print(core->vm_info, core," res4 : 0x%llx\n", (uint64_t) t->res4);
+    V3_Print(core->vm_info, core," iomap_base : 0x%llx\n", (uint64_t) t->iomap_base);
+    V3_Print(core->vm_info, core," (following io permission bitmap not currently printed)\n");
+
+}
+
 void v3_print_gp_error(struct guest_info * core, addr_t exit_info1) {
     struct selector_error_code * error = (struct selector_error_code *)(&exit_info1);
 
-    PrintDebug(core->vm_info, core, "      selector index: %x, TI: %x, IDT: %x, EXT: %x (error=%llx)\n",
+    if (v3_get_vm_cpu_mode(core)!=LONG) { 
+       V3_Print(core->vm_info, core, "= IDT ========\n");
+       V3_Print(core->vm_info, core, "(currently only supported in long mode)\n");
+       return;
+    }
+
+    V3_Print(core->vm_info, core, "      selector index: %x, TI: %x, IDT: %x, EXT: %x (error=%llx)\n",
             error->index, error->ti, error->idt, error->ext,
             (unsigned long long)exit_info1);
 }