#include <palacios/vmm.h>
#include <palacios/vmm_regs.h>
+#define NUM_IDT_ENTRIES 256
+#define NUM_GDT_ENTRIES 16
+
+struct segment_selector {
+ uint8_t rpl : 2;
+ uint8_t ti : 1;
+ uint16_t index : 13;
+}__attribute__((packed));
+
+struct int_trap_gate_long {
+ uint16_t offset_lo : 16;
+ uint16_t selector : 16;
+ uint8_t ist : 3;
+ uint8_t ign : 5;
+ uint8_t type : 4;
+ uint8_t s : 1;
+ uint8_t dpl : 2;
+ uint8_t p : 1;
+ uint16_t offset_mid : 16;
+ uint32_t offset_hi : 32;
+ uint32_t ign2 : 32;
+}__attribute__((packed));
+
+struct call_gate_long {
+ uint16_t offset_lo : 16;
+ uint16_t selector : 16;
+ uint8_t ign : 8;
+ uint8_t type : 4;
+ uint8_t s : 1;
+ uint8_t dpl : 2;
+ uint8_t p : 1;
+ uint16_t offset_mid : 16;
+ uint32_t offset_hi : 32;
+ uint8_t ign2 : 8;
+ uint8_t count : 5;
+ uint32_t ign3 : 19;
+}__attribute__((packed));
+
+struct system_desc_long {
+ uint16_t limit_lo : 16;
+ uint16_t base_lo : 16;
+ uint8_t base_mid1 : 8;
+ uint8_t type : 4;
+ uint8_t s : 1;
+ uint8_t dpl : 2;
+ uint8_t p : 1;
+ uint8_t limit_hi : 4;
+ uint8_t avl : 1;
+ uint8_t ign : 2;
+ uint8_t g : 1;
+ uint8_t base_mid2 : 8;
+ uint32_t base_hi : 32;
+ uint8_t ign2 : 8;
+ uint8_t lgcy_type : 5;
+ uint32_t ign3 : 19;
+}__attribute__((packed));
+
+struct data_desc_long {
+ uint16_t limit_lo : 16;
+ uint16_t base_lo : 16;
+ uint8_t base_mid : 8;
+ uint8_t a : 1;
+ uint8_t w : 1;
+ uint8_t e : 1;
+ uint8_t zero : 1;
+ uint8_t one : 1;
+ uint8_t dpl : 2;
+ uint8_t p : 1;
+ uint8_t limit_hi : 4;
+ uint8_t avl : 1;
+ uint8_t ign : 1;
+ uint8_t db : 1;
+ uint8_t g : 1;
+ uint8_t base_hi : 8;
+}__attribute__((packed));
+
+struct code_desc_long {
+ uint16_t limit_lo : 16;
+ uint16_t base_lo : 16;
+ uint8_t base_mid : 8;
+ uint8_t a : 1;
+ uint8_t r : 1;
+ uint8_t c : 1;
+ uint8_t one1 : 1;
+ uint8_t one2 : 1;
+ uint8_t dpl : 2;
+ uint8_t p : 1;
+ uint8_t limit_hi : 4;
+ uint8_t avl : 1;
+ uint8_t l : 1;
+ uint8_t d : 1;
+ uint8_t g : 1;
+ uint8_t base_hi : 8;
+}__attribute__((packed));
+
+struct int_trap_gate_lgcy {
+ uint16_t offset_lo : 16;
+ uint16_t selector : 16;
+ uint8_t ign : 8;
+ uint8_t type : 4;
+ uint8_t s : 1;
+ uint8_t dpl : 2;
+ uint8_t p : 1;
+ uint16_t offset_hi : 16;
+}__attribute__((packed));
+
+struct call_gate_lgcy {
+ uint16_t offset_lo : 16;
+ uint16_t selector : 16;
+ uint8_t count : 4;
+ uint8_t ign : 4;
+ uint8_t type : 4;
+ uint8_t s : 1;
+ uint8_t dpl : 2;
+ uint8_t p : 1;
+ uint16_t offset_hi : 16;
+}__attribute__((packed));
+
+struct trap_gate_lgcy {
+ uint16_t ign : 16;
+ uint16_t selector : 16;
+ uint8_t ign2 : 8;
+ uint8_t type : 4;
+ uint8_t s : 1;
+ uint8_t dpl : 2;
+ uint8_t p : 1;
+ uint16_t ign3 : 16;
+}__attribute__((packed));
+
+struct system_desc_lgcy {
+ uint16_t limit_lo : 16;
+ uint16_t base_lo : 16;
+ uint8_t base_mid : 8;
+ uint8_t type : 4;
+ uint8_t s : 1;
+ uint8_t dpl : 2;
+ uint8_t p : 1;
+ uint8_t limit_hi : 4;
+ uint8_t avl : 1;
+ uint8_t ign : 2;
+ uint8_t g : 1;
+ uint8_t base_hi : 8;
+}__attribute__((packed));
+
+struct data_desc_lgcy {
+ uint16_t limit_lo : 16;
+ uint16_t base_lo : 16;
+ uint8_t base_mid : 8;
+ uint8_t type : 4;
+ uint8_t s : 1;
+ uint8_t dpl : 2;
+ uint8_t p : 1;
+ uint8_t limit_hi : 4;
+ uint8_t avl : 1;
+ uint8_t ign : 1;
+ uint8_t db : 1;
+ uint8_t g : 1;
+ uint8_t base_hi : 8;
+}__attribute__((packed));
+
+struct code_desc_lgcy {
+ uint16_t limit_lo : 16;
+ uint16_t base_lo : 16;
+ uint8_t base_mid : 8;
+ uint8_t type : 4;
+ uint8_t s : 1;
+ uint8_t dpl : 2;
+ uint8_t p : 1;
+ uint8_t limit_hi : 4;
+ uint8_t avl : 1;
+ uint8_t ign : 1;
+ uint8_t d : 1;
+ uint8_t g : 1;
+ uint8_t base_hi : 8;
+}__attribute__((packed));
+
+
+struct selector_error_code {
+ uint8_t ext : 1;
+ uint8_t idt : 1;
+ uint8_t ti : 1;
+ uint16_t index : 13;
+ uint16_t ign : 16;
+}__attribute__((packed));
+
+
int v3_init_vm_debugging(struct v3_vm_info * vm);
void v3_print_guest_state(struct guest_info * core);
void v3_print_stack(struct guest_info * core);
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_gp_error(struct guest_info * core, addr_t exit_info1);
+
#endif // !__V3VEE__
#endif
}
}
+void v3_print_idt(struct guest_info * core, addr_t idtr_base) {
+ addr_t base_hva;
+
+ if (core->mem_mode == PHYSICAL_MEM) {
+ v3_gpa_to_hva(core,
+ get_addr_linear(core, idtr_base, &(core->segments.cs)),
+ &base_hva);
+ PrintError(core->vm_info, core, "Kind of weird that we got here.... physical mem?\n");
+ } else if (core->mem_mode == VIRTUAL_MEM) {
+ v3_gva_to_hva(core,
+ get_addr_linear(core, idtr_base, &(core->segments.cs)),
+ &base_hva);
+ }
+
+ // SANITY CHECK
+ if (idtr_base != get_addr_linear(core, idtr_base, &(core->segments.cs))) {
+ PrintError(core->vm_info, core, "idtr base address != linear translation, might be something funky with cs\n");
+ }
+
+ int i;
+ char *types[16] = {" ILGL","aTSS16"," LDT","bTSS16","call16"," task","intr16","trap16",
+ " ILGL","aTSS32"," ILGL","bTSS32","call32"," ILGL","intr32","trap32"};
+
+ 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");
+ 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,
+ entry->selector,
+ seg->index, seg->ti, seg->rpl,
+ entry->offset_hi, entry->offset_lo,
+ types[entry->type], entry->dpl, entry->s, entry->p);
+ entry++;
+ }
+}
+
+void v3_print_gdt(struct guest_info * core, addr_t gdtr_base) {
+ addr_t base_hva;
+
+ if (core->mem_mode == PHYSICAL_MEM) {
+ v3_gpa_to_hva(core,
+ get_addr_linear(core, gdtr_base, &(core->segments.cs)),
+ &base_hva);
+ PrintError(core->vm_info, core, "Kind of weird that we got here.... physical mem?\n");
+ } else if (core->mem_mode == VIRTUAL_MEM) {
+ v3_gva_to_hva(core,
+ get_addr_linear(core, gdtr_base, &(core->segments.cs)),
+ &base_hva);
+ }
+
+ // SANITY CHECK
+ if (gdtr_base != get_addr_linear(core, gdtr_base, &(core->segments.cs))) {
+ PrintError(core->vm_info, core, "gdtr base address != linear translation, might be something funky with cs\n");
+ }
+
+ int i;
+ char* cd[2] = {"code","data"};
+ // 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");
+ 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,
+ 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_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",
+ error->index, error->ti, error->idt, error->ext,
+ (unsigned long long)exit_info1);
+}
+
#elif __V3_64BIT__
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 (core->mem_mode == PHYSICAL_MEM) {
+ v3_gpa_to_hva(core,
+ get_addr_linear(core, idtr_base, &(core->segments.cs)),
+ &base_hva);
+ } else if (core->mem_mode == VIRTUAL_MEM) {
+ v3_gva_to_hva(core,
+ get_addr_linear(core, idtr_base, &(core->segments.cs)),
+ &base_hva);
+ }
+
+ // SANITY CHECK
+ if (idtr_base != get_addr_linear(core, idtr_base, &(core->segments.cs))) {
+ PrintError(core->vm_info, core, "idtr base address != linear translation, might be something funky with cs\n");
+ }
+
+ int i;
+ char *types[16] = {"ILGL","ILGL"," LDT","ILGL","ILGL","ILGL","ILGL","ILGL","ILGL",
+ "aTSS","ILGL","bTSS","call","ILGL","intr","trap"};
+
+ 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");
+ 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,
+ entry->selector,
+ seg->index, seg->ti, seg->rpl,
+ entry->offset_hi, entry->offset_mid, entry->offset_lo,
+ types[entry->type], entry->dpl, entry->s,
+ entry->s, entry->p);
+ entry++;
+ }
+}
+
+void v3_print_gdt(struct guest_info * core, addr_t gdtr_base) {
+ addr_t base_hva;
+
+ if (core->mem_mode == PHYSICAL_MEM) {
+ v3_gpa_to_hva(core,
+ get_addr_linear(core, gdtr_base, &(core->segments.cs)),
+ &base_hva);
+ } else if (core->mem_mode == VIRTUAL_MEM) {
+ v3_gva_to_hva(core,
+ get_addr_linear(core, gdtr_base, &(core->segments.cs)),
+ &base_hva);
+ }
+
+ // SANITY CHECK
+ if (gdtr_base != get_addr_linear(core, gdtr_base, &(core->segments.cs))) {
+ PrintError(core->vm_info, core, "gdtr base address != linear translation, might be something funky with cs\n");
+ }
+
+ int i;
+ char* cd[2] = {"code","data"};
+ // 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");
+ 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,
+ 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_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",
+ error->index, error->ti, error->idt, error->ext,
+ (unsigned long long)exit_info1);
+}
+
#endif