struct svm_io_info {
- uint_t type : 1 PACKED; // (0=out, 1=in)
- uint_t rsvd : 1 PACKED; // Must be Zero
- uint_t str : 1 PACKED; // string based io
- uint_t rep : 1 PACKED; // repeated io
- uint_t sz8 : 1 PACKED; // 8 bit op size
- uint_t sz16 : 1 PACKED; // 16 bit op size
- uint_t sz32 : 1 PACKED; // 32 bit op size
- uint_t addr16 : 1 PACKED; // 16 bit addr
- uint_t addr32 : 1 PACKED; // 32 bit addr
- uint_t addr64 : 1 PACKED; // 64 bit addr
- uint_t rsvd2 : 6 PACKED; // Should be Zero
- ushort_t port PACKED; // port number
+ uint_t type : 1 PACKED; // (0=out, 1=in)
+ uint_t rsvd : 1 PACKED; // Must be Zero
+ uint_t str : 1 PACKED; // string based io
+ uint_t rep : 1 PACKED; // repeated io
+ uint_t sz8 : 1 PACKED; // 8 bit op size
+ uint_t sz16 : 1 PACKED; // 16 bit op size
+ uint_t sz32 : 1 PACKED; // 32 bit op size
+ uint_t addr16 : 1 PACKED; // 16 bit addr
+ uint_t addr32 : 1 PACKED; // 32 bit addr
+ uint_t addr64 : 1 PACKED; // 64 bit addr
+ uint_t rsvd2 : 6 PACKED; // Should be Zero
+ ushort_t port PACKED; // port number
};
struct vm_device_ops {
- int (*init)(struct vm_device *dev);
- int (*deinit)(struct vm_device *dev);
+ int (*init)(struct vm_device *dev);
+ int (*deinit)(struct vm_device *dev);
- int (*reset)(struct vm_device *dev);
+ int (*reset)(struct vm_device *dev);
- int (*start)(struct vm_device *dev);
- int (*stop)(struct vm_device *dev);
+ int (*start)(struct vm_device *dev);
+ int (*stop)(struct vm_device *dev);
- //int (*save)(struct vm_device *dev, struct *iostream);
- //int (*restore)(struct vm_device *dev, struct *iostream);
+ //int (*save)(struct vm_device *dev, struct *iostream);
+ //int (*restore)(struct vm_device *dev, struct *iostream);
};
struct vm_device {
- char name[32];
+ char name[32];
- void *private_data;
+ void *private_data;
- struct vm_device_ops * ops;
+ struct vm_device_ops * ops;
- struct guest_info * vm;
+ struct guest_info * vm;
- struct list_head dev_link;
+ struct list_head dev_link;
- uint_t num_io_hooks;
- struct list_head io_hooks;
- uint_t num_mem_hooks;
- struct list_head mem_hooks;
- uint_t num_irq_hooks;
- struct list_head irq_hooks;
+ uint_t num_io_hooks;
+ struct list_head io_hooks;
+ uint_t num_mem_hooks;
+ struct list_head mem_hooks;
+ uint_t num_irq_hooks;
+ struct list_head irq_hooks;
};
int v3_dev_hook_io(struct vm_device *dev,
- ushort_t port,
- int (*read)(ushort_t port, void * dst, uint_t length, struct vm_device * dev),
- int (*write)(ushort_t port, void * src, uint_t length, struct vm_device * dev));
+ ushort_t port,
+ int (*read)(ushort_t port, void * dst, uint_t length, struct vm_device * dev),
+ int (*write)(ushort_t port, void * src, uint_t length, struct vm_device * dev));
int v3_dev_unhook_io(struct vm_device *dev,
- ushort_t port);
+ ushort_t port);
int v3_dev_hook_mem(struct vm_device *dev,
- void *start,
- void *end);
+ void *start,
+ void *end);
int v3_dev_unhook_mem(struct vm_device * dev,
- void * start,
- void * end);
+ void * start,
+ void * end);
int v3_dev_hook_irq(struct vm_device * dev,
- uint_t irq,
- int (*handler)(uint_t irq, struct vm_device * dev));
+ uint_t irq,
+ int (*handler)(uint_t irq, struct vm_device * dev));
int v3_dev_unhook_irq(struct vm_device * dev, uint_t irq);
struct v3_gprs {
- v3_reg_t rdi;
- v3_reg_t rsi;
- v3_reg_t rbp;
- v3_reg_t rsp;
- v3_reg_t rbx;
- v3_reg_t rdx;
- v3_reg_t rcx;
- v3_reg_t rax;
-
- v3_reg_t r8;
- v3_reg_t r9;
- v3_reg_t r10;
- v3_reg_t r11;
- v3_reg_t r12;
- v3_reg_t r13;
- v3_reg_t r14;
- v3_reg_t r15;
+ v3_reg_t rdi;
+ v3_reg_t rsi;
+ v3_reg_t rbp;
+ v3_reg_t rsp;
+ v3_reg_t rbx;
+ v3_reg_t rdx;
+ v3_reg_t rcx;
+ v3_reg_t rax;
+
+ v3_reg_t r8;
+ v3_reg_t r9;
+ v3_reg_t r10;
+ v3_reg_t r11;
+ v3_reg_t r12;
+ v3_reg_t r13;
+ v3_reg_t r14;
+ v3_reg_t r15;
} __attribute__((packed));
struct v3_ctrl_regs {
- v3_reg_t cr0;
- v3_reg_t cr2;
- v3_reg_t cr3;
- v3_reg_t cr4;
- v3_reg_t cr8;
- v3_reg_t rflags;
- v3_reg_t efer;
+ v3_reg_t cr0;
+ v3_reg_t cr2;
+ v3_reg_t cr3;
+ v3_reg_t cr4;
+ v3_reg_t cr8;
+ v3_reg_t rflags;
+ v3_reg_t efer;
};
struct v3_dbg_regs {
- v3_reg_t dr0;
- v3_reg_t dr1;
- v3_reg_t dr2;
- v3_reg_t dr3;
- v3_reg_t dr6;
- v3_reg_t dr7;
+ v3_reg_t dr0;
+ v3_reg_t dr1;
+ v3_reg_t dr2;
+ v3_reg_t dr3;
+ v3_reg_t dr6;
+ v3_reg_t dr7;
};
struct v3_segment {
- ushort_t selector;
- uint_t limit;
- ullong_t base;
- uint_t type : 4;
- uint_t system : 1;
- uint_t dpl : 2;
- uint_t present : 1;
- uint_t avail : 1;
- uint_t long_mode : 1;
- uint_t db : 1;
- uint_t granularity : 1;
+ ushort_t selector;
+ uint_t limit;
+ ullong_t base;
+ uint_t type : 4;
+ uint_t system : 1;
+ uint_t dpl : 2;
+ uint_t present : 1;
+ uint_t avail : 1;
+ uint_t long_mode : 1;
+ uint_t db : 1;
+ uint_t granularity : 1;
} __attribute__((packed));
struct v3_segments {
- struct v3_segment cs;
- struct v3_segment ds;
- struct v3_segment es;
- struct v3_segment fs;
- struct v3_segment gs;
- struct v3_segment ss;
- struct v3_segment ldtr;
- struct v3_segment gdtr;
- struct v3_segment idtr;
- struct v3_segment tr;
+ struct v3_segment cs;
+ struct v3_segment ds;
+ struct v3_segment es;
+ struct v3_segment fs;
+ struct v3_segment gs;
+ struct v3_segment ss;
+ struct v3_segment ldtr;
+ struct v3_segment gdtr;
+ struct v3_segment idtr;
+ struct v3_segment tr;
};
struct shadow_page_state;
struct guest_info {
- ullong_t rip;
+ ullong_t rip;
- uint_t cpl;
+ uint_t cpl;
- addr_t mem_size; // In bytes for now
- v3_shdw_map_t mem_map;
+ addr_t mem_size; // In bytes for now
+ v3_shdw_map_t mem_map;
- struct vm_time time_state;
+ struct vm_time time_state;
- v3_paging_mode_t shdw_pg_mode;
- struct shadow_page_state shdw_pg_state;
- addr_t direct_map_pt;
- // nested_paging_t nested_page_state;
+ v3_paging_mode_t shdw_pg_mode;
+ struct shadow_page_state shdw_pg_state;
+ addr_t direct_map_pt;
+ // nested_paging_t nested_page_state;
- // This structure is how we get interrupts for the guest
- struct v3_intr_state intr_state;
+ // This structure is how we get interrupts for the guest
+ struct v3_intr_state intr_state;
- v3_io_map_t io_map;
+ v3_io_map_t io_map;
- struct v3_msr_map msr_map;
+ struct v3_msr_map msr_map;
- v3_hypercall_map_t hcall_map;
+ v3_hypercall_map_t hcall_map;
- // device_map
- struct vmm_dev_mgr dev_mgr;
+ // device_map
+ struct vmm_dev_mgr dev_mgr;
- struct v3_host_events host_event_hooks;
+ struct v3_host_events host_event_hooks;
- v3_vm_cpu_mode_t cpu_mode;
- v3_vm_mem_mode_t mem_mode;
- uint_t addr_width;
+ v3_vm_cpu_mode_t cpu_mode;
+ v3_vm_mem_mode_t mem_mode;
+ uint_t addr_width;
- struct v3_gprs vm_regs;
- struct v3_ctrl_regs ctrl_regs;
- struct v3_dbg_regs dbg_regs;
- struct v3_segments segments;
+ struct v3_gprs vm_regs;
+ struct v3_ctrl_regs ctrl_regs;
+ struct v3_dbg_regs dbg_regs;
+ struct v3_segments segments;
- v3_vm_operating_mode_t run_state;
- void * vmm_data;
+ v3_vm_operating_mode_t run_state;
+ void * vmm_data;
- uint_t enable_profiler;
- struct v3_profiler profiler;
+ uint_t enable_profiler;
+ struct v3_profiler profiler;
- void * decoder_state;
+ void * decoder_state;
- v3_msr_t guest_efer;
+ v3_msr_t guest_efer;
- /* Do we need these ? */
- v3_msr_t guest_star;
- v3_msr_t guest_lstar;
- v3_msr_t guest_cstar;
- v3_msr_t guest_syscall_mask;
- v3_msr_t guest_gs_base;
+ /* Do we need these ? */
+ v3_msr_t guest_star;
+ v3_msr_t guest_lstar;
+ v3_msr_t guest_cstar;
+ v3_msr_t guest_syscall_mask;
+ v3_msr_t guest_gs_base;
- uint64_t fs;
- uint64_t gs;
+ uint64_t fs;
+ uint64_t gs;
struct Ctrl_Registers {
- uint_t cr0 : 1;
- uint_t cr1 : 1;
- uint_t cr2 : 1;
- uint_t cr3 : 1;
- uint_t cr4 : 1;
- uint_t cr5 : 1;
- uint_t cr6 : 1;
- uint_t cr7 : 1;
- uint_t cr8 : 1;
- uint_t cr9 : 1;
- uint_t cr10 : 1;
- uint_t cr11 : 1;
- uint_t cr12 : 1;
- uint_t cr13 : 1;
- uint_t cr14 : 1;
- uint_t cr15 : 1;
+ uint_t cr0 : 1;
+ uint_t cr1 : 1;
+ uint_t cr2 : 1;
+ uint_t cr3 : 1;
+ uint_t cr4 : 1;
+ uint_t cr5 : 1;
+ uint_t cr6 : 1;
+ uint_t cr7 : 1;
+ uint_t cr8 : 1;
+ uint_t cr9 : 1;
+ uint_t cr10 : 1;
+ uint_t cr11 : 1;
+ uint_t cr12 : 1;
+ uint_t cr13 : 1;
+ uint_t cr14 : 1;
+ uint_t cr15 : 1;
} __attribute__((packed));
struct Instr_Intercepts {
- uint_t INTR : 1;
- uint_t NMI : 1;
- uint_t SMI : 1;
- uint_t INIT : 1;
- uint_t VINTR : 1;
- uint_t CR0 : 1;
- uint_t RD_IDTR : 1;
- uint_t RD_GDTR : 1;
- uint_t RD_LDTR : 1;
- uint_t RD_TR : 1;
- uint_t WR_IDTR : 1;
- uint_t WR_GDTR : 1;
- uint_t WR_LDTR : 1;
- uint_t WR_TR : 1;
- uint_t RDTSC : 1;
- uint_t RDPMC : 1;
- uint_t PUSHF : 1;
- uint_t POPF : 1;
- uint_t CPUID : 1;
- uint_t RSM : 1;
- uint_t IRET : 1;
- uint_t INTn : 1;
- uint_t INVD : 1;
- uint_t PAUSE : 1;
- uint_t HLT : 1;
- uint_t INVLPG : 1;
- uint_t INVLPGA : 1;
- uint_t IOIO_PROT : 1;
- uint_t MSR_PROT : 1;
- uint_t task_switch : 1;
- uint_t FERR_FREEZE : 1;
- uint_t shutdown_evts: 1;
+ uint_t INTR : 1;
+ uint_t NMI : 1;
+ uint_t SMI : 1;
+ uint_t INIT : 1;
+ uint_t VINTR : 1;
+ uint_t CR0 : 1;
+ uint_t RD_IDTR : 1;
+ uint_t RD_GDTR : 1;
+ uint_t RD_LDTR : 1;
+ uint_t RD_TR : 1;
+ uint_t WR_IDTR : 1;
+ uint_t WR_GDTR : 1;
+ uint_t WR_LDTR : 1;
+ uint_t WR_TR : 1;
+ uint_t RDTSC : 1;
+ uint_t RDPMC : 1;
+ uint_t PUSHF : 1;
+ uint_t POPF : 1;
+ uint_t CPUID : 1;
+ uint_t RSM : 1;
+ uint_t IRET : 1;
+ uint_t INTn : 1;
+ uint_t INVD : 1;
+ uint_t PAUSE : 1;
+ uint_t HLT : 1;
+ uint_t INVLPG : 1;
+ uint_t INVLPGA : 1;
+ uint_t IOIO_PROT : 1;
+ uint_t MSR_PROT : 1;
+ uint_t task_switch : 1;
+ uint_t FERR_FREEZE : 1;
+ uint_t shutdown_evts: 1;
} __attribute__((packed));
struct SVM_Instr_Intercepts {
- uint_t VMRUN : 1;
- uint_t VMMCALL : 1;
- uint_t VMLOAD : 1;
- uint_t VMSAVE : 1;
- uint_t STGI : 1;
- uint_t CLGI : 1;
- uint_t SKINIT : 1;
- uint_t RDTSCP : 1;
- uint_t ICEBP : 1;
- uint_t WBINVD : 1;
- uint_t MONITOR : 1;
- uint_t MWAIT_always : 1;
- uint_t MWAIT_if_armed : 1;
- uint_t reserved : 19; // Should be 0
+ uint_t VMRUN : 1;
+ uint_t VMMCALL : 1;
+ uint_t VMLOAD : 1;
+ uint_t VMSAVE : 1;
+ uint_t STGI : 1;
+ uint_t CLGI : 1;
+ uint_t SKINIT : 1;
+ uint_t RDTSCP : 1;
+ uint_t ICEBP : 1;
+ uint_t WBINVD : 1;
+ uint_t MONITOR : 1;
+ uint_t MWAIT_always : 1;
+ uint_t MWAIT_if_armed : 1;
+ uint_t reserved : 19; // Should be 0
} __attribute__((packed));
struct Guest_Control {
- uchar_t V_TPR;
- uint_t V_IRQ : 1;
- uint_t rsvd1 : 7; // Should be 0
- uint_t V_INTR_PRIO : 4;
- uint_t V_IGN_TPR : 1;
- uint_t rsvd2 : 3; // Should be 0
- uint_t V_INTR_MASKING : 1;
- uint_t rsvd3 : 7; // Should be 0
- uchar_t V_INTR_VECTOR;
- uint_t rsvd4 : 24; // Should be 0
+ uchar_t V_TPR;
+ uint_t V_IRQ : 1;
+ uint_t rsvd1 : 7; // Should be 0
+ uint_t V_INTR_PRIO : 4;
+ uint_t V_IGN_TPR : 1;
+ uint_t rsvd2 : 3; // Should be 0
+ uint_t V_INTR_MASKING : 1;
+ uint_t rsvd3 : 7; // Should be 0
+ uchar_t V_INTR_VECTOR;
+ uint_t rsvd4 : 24; // Should be 0
} __attribute__((packed));
#define SVM_INJECTION_EXTERNAL_INTR 0
#define SVM_INJECTION_SOFT_INTR 4
struct Interrupt_Info {
- uint_t vector : 8;
- uint_t type : 3;
- uint_t ev : 1;
- uint_t rsvd : 19;
- uint_t valid : 1;
- uint_t error_code : 32;
+ uint_t vector : 8;
+ uint_t type : 3;
+ uint_t ev : 1;
+ uint_t rsvd : 19;
+ uint_t valid : 1;
+ uint_t error_code : 32;
} __attribute__((packed));
struct VMCB_Control_Area {
- // offset 0x0
- struct Ctrl_Registers cr_reads;
- struct Ctrl_Registers cr_writes;
- struct Debug_Registers dr_reads;
- struct Debug_Registers dr_writes;
- struct Exception_Vectors exceptions;
- struct Instr_Intercepts instrs;
- struct SVM_Instr_Intercepts svm_instrs;
+ // offset 0x0
+ struct Ctrl_Registers cr_reads;
+ struct Ctrl_Registers cr_writes;
+ struct Debug_Registers dr_reads;
+ struct Debug_Registers dr_writes;
+ struct Exception_Vectors exceptions;
+ struct Instr_Intercepts instrs;
+ struct SVM_Instr_Intercepts svm_instrs;
- uchar_t rsvd1[44]; // Should be 0
+ uchar_t rsvd1[44]; // Should be 0
- // offset 0x040
- ullong_t IOPM_BASE_PA;
- ullong_t MSRPM_BASE_PA;
- ullong_t TSC_OFFSET;
+ // offset 0x040
+ ullong_t IOPM_BASE_PA;
+ ullong_t MSRPM_BASE_PA;
+ ullong_t TSC_OFFSET;
- uint_t guest_ASID;
- uchar_t TLB_CONTROL;
+ uint_t guest_ASID;
+ uchar_t TLB_CONTROL;
- uchar_t rsvd2[3]; // Should be 0
+ uchar_t rsvd2[3]; // Should be 0
- struct Guest_Control guest_ctrl;
+ struct Guest_Control guest_ctrl;
- uint_t interrupt_shadow : 1;
- uint_t rsvd3 : 31; // Should be 0
- uint_t rsvd4; // Should be 0
+ uint_t interrupt_shadow : 1;
+ uint_t rsvd3 : 31; // Should be 0
+ uint_t rsvd4; // Should be 0
- ullong_t exit_code;
- ullong_t exit_info1;
- ullong_t exit_info2;
+ ullong_t exit_code;
+ ullong_t exit_info1;
+ ullong_t exit_info2;
- /* This could be a typo in the manual....
- * It doesn't actually say that there is a reserved bit
- * But it does say that the EXITINTINFO field is in bits 63-1
- * ALL other occurances mention a 1 bit reserved field
- */
- // uint_t rsvd5 : 1;
- //ullong_t exit_int_info : 63;
- /* ** */
+ /* This could be a typo in the manual....
+ * It doesn't actually say that there is a reserved bit
+ * But it does say that the EXITINTINFO field is in bits 63-1
+ * ALL other occurances mention a 1 bit reserved field
+ */
+ // uint_t rsvd5 : 1;
+ //ullong_t exit_int_info : 63;
+ /* ** */
- // AMD Manual 2, pg 391, sect: 15.19
- struct Interrupt_Info exit_int_info;
+ // AMD Manual 2, pg 391, sect: 15.19
+ struct Interrupt_Info exit_int_info;
- // uint_t NP_ENABLE : 1;
- //ullong_t rsvd6 : 63; // Should be 0
- ullong_t NP_ENABLE;
+ // uint_t NP_ENABLE : 1;
+ //ullong_t rsvd6 : 63; // Should be 0
+ ullong_t NP_ENABLE;
- uchar_t rsvd7[16]; // Should be 0
+ uchar_t rsvd7[16]; // Should be 0
- // Offset 0xA8
- struct Interrupt_Info EVENTINJ;
+ // Offset 0xA8
+ struct Interrupt_Info EVENTINJ;
- /* This could be a typo in the manual....
- * It doesn't actually say that there is a reserved bit
- * But it does say that the EXITINTINFO field is in bits 63-1
- * ALL other occurances mention a 1 bit reserved field
- */
- // uint_t rsvd8 : 1;
- //ullong_t N_CR3 : 63;
- ullong_t N_CR3;
- /* ** */
+ /* This could be a typo in the manual....
+ * It doesn't actually say that there is a reserved bit
+ * But it does say that the EXITINTINFO field is in bits 63-1
+ * ALL other occurances mention a 1 bit reserved field
+ */
+ // uint_t rsvd8 : 1;
+ //ullong_t N_CR3 : 63;
+ ullong_t N_CR3;
+ /* ** */
- uint_t LBR_VIRTUALIZATION_ENABLE : 1;
- ullong_t rsvd9 : 63; // Should be 0
+ uint_t LBR_VIRTUALIZATION_ENABLE : 1;
+ ullong_t rsvd9 : 63; // Should be 0
} __attribute__((packed));
struct vmcb_selector {
- ushort_t selector;
-
- /* These attributes are basically a direct map of the attribute fields of a segment desc.
- * The segment limit in the middle is removed and the fields are fused together
- * There IS empty space at the end... See AMD Arch vol3, sect. 4.7.1, pg 78
- */
- union {
- ushort_t raw;
- struct {
- uint_t type : 4; // segment type, [see Intel vol. 3b, sect. 3.4.5.1 (because I have the books)]
- uint_t S : 1; // System=0, code/data=1
- uint_t dpl : 2; // priviledge level, corresonds to protection ring
- uint_t P : 1; // present flag
- uint_t avl : 1; // available for use by system software
- uint_t L : 1; // long mode (64 bit?)
- uint_t db : 1; // default op size (0=16 bit seg, 1=32 bit seg)
- uint_t G : 1; // Granularity, (0=bytes, 1=4k)
- uint_t rsvd : 4;
- } __attribute__((packed)) fields;
- } __attribute__((packed)) attrib;
-
- uint_t limit;
- ullong_t base;
+ ushort_t selector;
+
+ /* These attributes are basically a direct map of the attribute fields of a segment desc.
+ * The segment limit in the middle is removed and the fields are fused together
+ * There IS empty space at the end... See AMD Arch vol3, sect. 4.7.1, pg 78
+ */
+ union {
+ ushort_t raw;
+ struct {
+ uint_t type : 4; // segment type, [see Intel vol. 3b, sect. 3.4.5.1 (because I have the books)]
+ uint_t S : 1; // System=0, code/data=1
+ uint_t dpl : 2; // priviledge level, corresonds to protection ring
+ uint_t P : 1; // present flag
+ uint_t avl : 1; // available for use by system software
+ uint_t L : 1; // long mode (64 bit?)
+ uint_t db : 1; // default op size (0=16 bit seg, 1=32 bit seg)
+ uint_t G : 1; // Granularity, (0=bytes, 1=4k)
+ uint_t rsvd : 4;
+ } __attribute__((packed)) fields;
+ } __attribute__((packed)) attrib;
+
+ uint_t limit;
+ ullong_t base;
} __attribute__((packed));
struct VMCB_State_Save_Area {
- struct vmcb_selector es; // only lower 32 bits of base are implemented
- struct vmcb_selector cs; // only lower 32 bits of base are implemented
- struct vmcb_selector ss; // only lower 32 bits of base are implemented
- struct vmcb_selector ds; // only lower 32 bits of base are implemented
- struct vmcb_selector fs;
- struct vmcb_selector gs;
+ struct vmcb_selector es; // only lower 32 bits of base are implemented
+ struct vmcb_selector cs; // only lower 32 bits of base are implemented
+ struct vmcb_selector ss; // only lower 32 bits of base are implemented
+ struct vmcb_selector ds; // only lower 32 bits of base are implemented
+ struct vmcb_selector fs;
+ struct vmcb_selector gs;
- struct vmcb_selector gdtr; // selector+attrib are reserved, only lower 16 bits of limit are implemented
- struct vmcb_selector ldtr;
- struct vmcb_selector idtr; // selector+attrib are reserved, only lower 16 bits of limit are implemented
- struct vmcb_selector tr;
+ struct vmcb_selector gdtr; // selector+attrib are reserved, only lower 16 bits of limit are implemented
+ struct vmcb_selector ldtr;
+ struct vmcb_selector idtr; // selector+attrib are reserved, only lower 16 bits of limit are implemented
+ struct vmcb_selector tr;
- uchar_t rsvd1[43];
+ uchar_t rsvd1[43];
- //offset 0x0cb
- uchar_t cpl; // if the guest is real-mode then the CPL is forced to 0
- // if the guest is virtual-mode then the CPL is forced to 3
+ //offset 0x0cb
+ uchar_t cpl; // if the guest is real-mode then the CPL is forced to 0
+ // if the guest is virtual-mode then the CPL is forced to 3
- uint_t rsvd2;
+ uint_t rsvd2;
- // offset 0x0d0
- ullong_t efer;
+ // offset 0x0d0
+ ullong_t efer;
- uchar_t rsvd3[112];
+ uchar_t rsvd3[112];
- //offset 0x148
- ullong_t cr4;
- ullong_t cr3;
- ullong_t cr0;
- ullong_t dr7;
- ullong_t dr6;
- ullong_t rflags;
- ullong_t rip;
-
- uchar_t rsvd4[88];
+ //offset 0x148
+ ullong_t cr4;
+ ullong_t cr3;
+ ullong_t cr0;
+ ullong_t dr7;
+ ullong_t dr6;
+ ullong_t rflags;
+ ullong_t rip;
+
+ uchar_t rsvd4[88];
- //offset 0x1d8
- ullong_t rsp;
-
- uchar_t rsvd5[24];
-
- //offset 0x1f8
- ullong_t rax;
- ullong_t star;
- ullong_t lstar;
- ullong_t cstar;
- ullong_t sfmask;
- ullong_t KernelGsBase;
- ullong_t sysenter_cs;
- ullong_t sysenter_esp;
- ullong_t sysenter_eip;
- ullong_t cr2;
-
-
- uchar_t rsvd6[32];
-
- //offset 0x268
- ullong_t g_pat; // Guest PAT
- // -- only used if nested paging is enabled
- ullong_t dbgctl; // Guest DBGCTL MSR
- // -- only used if the LBR registers are virtualized
- ullong_t br_from; // Guest LastBranchFromIP MSR
- // -- only used if the LBR registers are virtualized
- ullong_t br_to; // Guest LastBranchToIP MSR
- // -- only used if the LBR registers are virtualized
- ullong_t lastexcpfrom; // Guest LastExceptionFromIP MSR
- // -- only used if the LBR registers are virtualized
- ullong_t lastexcpto; // Guest LastExceptionToIP MSR
- // -- only used if the LBR registers are virtualized
+ //offset 0x1d8
+ ullong_t rsp;
+
+ uchar_t rsvd5[24];
+
+ //offset 0x1f8
+ ullong_t rax;
+ ullong_t star;
+ ullong_t lstar;
+ ullong_t cstar;
+ ullong_t sfmask;
+ ullong_t KernelGsBase;
+ ullong_t sysenter_cs;
+ ullong_t sysenter_esp;
+ ullong_t sysenter_eip;
+ ullong_t cr2;
+
+
+ uchar_t rsvd6[32];
+
+ //offset 0x268
+ ullong_t g_pat; // Guest PAT
+ // -- only used if nested paging is enabled
+ ullong_t dbgctl; // Guest DBGCTL MSR
+ // -- only used if the LBR registers are virtualized
+ ullong_t br_from; // Guest LastBranchFromIP MSR
+ // -- only used if the LBR registers are virtualized
+ ullong_t br_to; // Guest LastBranchToIP MSR
+ // -- only used if the LBR registers are virtualized
+ ullong_t lastexcpfrom; // Guest LastExceptionFromIP MSR
+ // -- only used if the LBR registers are virtualized
+ ullong_t lastexcpto; // Guest LastExceptionToIP MSR
+ // -- only used if the LBR registers are virtualized
} __attribute__((packed));
#define PrintDebug(fmt, args...) \
- do { \
- extern struct v3_os_hooks * os_hooks; \
- if ((os_hooks) && (os_hooks)->print_debug) { \
- (os_hooks)->print_debug((fmt), ##args); \
- } \
- } while (0)
+ do { \
+ extern struct v3_os_hooks * os_hooks; \
+ if ((os_hooks) && (os_hooks)->print_debug) { \
+ (os_hooks)->print_debug((fmt), ##args); \
+ } \
+ } while (0)
#if 1
#else
#define PrintError(fmt, args...) \
- do { \
- extern struct v3_os_hooks * os_hooks; \
- if ((os_hooks) && (os_hooks)->print_debug) { \
- (os_hooks)->print_debug("%s(%d): " fmt, __FILE__, __LINE__, ##args); \
- } \
- } while (0)
+ do { \
+ extern struct v3_os_hooks * os_hooks; \
+ if ((os_hooks) && (os_hooks)->print_debug) { \
+ (os_hooks)->print_debug("%s(%d): " fmt, __FILE__, __LINE__, ##args); \
+ } \
+ } while (0)
#ifdef VMM_INFO
#define PrintInfo(fmt, args...) \
- do { \
- extern struct v3_os_hooks * os_hooks; \
- if ((os_hooks) && (os_hooks)->print_info) { \
- (os_hooks)->print_info((fmt), ##args); \
- } \
- } while (0)
+ do { \
+ extern struct v3_os_hooks * os_hooks; \
+ if ((os_hooks) && (os_hooks)->print_info) { \
+ (os_hooks)->print_info((fmt), ##args); \
+ } \
+ } while (0)
#else
#define PrintInfo(fmt, args...)
#endif
#ifdef VMM_TRACE
-#define PrintTrace(fmt, args...) \
- do { \
- extern struct v3_os_hooks * os_hooks; \
- if ((os_hooks) && (os_hooks)->print_trace) { \
- (os_hooks)->print_trace(fmt, ##args); \
- } \
- } while (0)
+#define PrintTrace(fmt, args...) \
+ do { \
+ extern struct v3_os_hooks * os_hooks; \
+ if ((os_hooks) && (os_hooks)->print_trace) { \
+ (os_hooks)->print_trace(fmt, ##args); \
+ } \
+ } while (0)
#else
#define PrintTrace(fmt, args...)
#endif
-#define V3_AllocPages(num_pages) \
- ({ \
- extern struct v3_os_hooks * os_hooks; \
- void * ptr = 0; \
- if ((os_hooks) && (os_hooks)->allocate_pages) { \
- ptr = (os_hooks)->allocate_pages(num_pages); \
- } \
- ptr; \
- }) \
-
-
-#define V3_FreePage(page) \
- do { \
- extern struct v3_os_hooks * os_hooks; \
- if ((os_hooks) && (os_hooks)->free_page) { \
- (os_hooks)->free_page(page); \
- } \
- } while(0) \
-
-
-#define V3_VAddr(addr) ({ \
- extern struct v3_os_hooks * os_hooks; \
- void * var = 0; \
- if ((os_hooks) && (os_hooks)->paddr_to_vaddr) { \
- var = (os_hooks)->paddr_to_vaddr(addr); \
- } \
- var; \
+#define V3_AllocPages(num_pages) \
+ ({ \
+ extern struct v3_os_hooks * os_hooks; \
+ void * ptr = 0; \
+ if ((os_hooks) && (os_hooks)->allocate_pages) { \
+ ptr = (os_hooks)->allocate_pages(num_pages); \
+ } \
+ ptr; \
})
-#define V3_PAddr(addr) ({ \
- extern struct v3_os_hooks * os_hooks; \
- void * var = 0; \
- if ((os_hooks) && (os_hooks)->vaddr_to_paddr) { \
- var = (os_hooks)->vaddr_to_paddr(addr); \
- } \
- var; \
- })
-
+#define V3_FreePage(page) \
+ do { \
+ extern struct v3_os_hooks * os_hooks; \
+ if ((os_hooks) && (os_hooks)->free_page) { \
+ (os_hooks)->free_page(page); \
+ } \
+ } while(0)
-#define V3_Malloc(size) ({ \
- extern struct v3_os_hooks * os_hooks; \
- void * var = 0; \
- if ((os_hooks) && (os_hooks)->malloc) { \
- var = (os_hooks)->malloc(size); \
- } \
- var; \
- })
+#define V3_VAddr(addr) ({ \
+ extern struct v3_os_hooks * os_hooks; \
+ void * var = 0; \
+ if ((os_hooks) && (os_hooks)->paddr_to_vaddr) { \
+ var = (os_hooks)->paddr_to_vaddr(addr); \
+ } \
+ var; \
+ })
-// We need to check the hook structure at runtime to ensure its SAFE
-#define V3_Free(addr) \
- do { \
- extern struct v3_os_hooks * os_hooks; \
- if ((os_hooks) && (os_hooks)->free) { \
- (os_hooks)->free(addr); \
- } \
- } while (0) \
-
-// uint_t V3_CPU_KHZ();
-#define V3_CPU_KHZ() \
- ({ \
- unsigned int khz = 0; \
- extern struct v3_os_hooks * os_hooks; \
- if ((os_hooks) && (os_hooks)->get_cpu_khz) { \
- khz = (os_hooks)->get_cpu_khz(); \
- } \
- khz; \
- }) \
-
-
-
-#define V3_Hook_Interrupt(irq, opaque) \
- ({ \
- int ret = 0; \
- extern struct v3_os_hooks * os_hooks; \
- if ((os_hooks) && (os_hooks)->hook_interrupt) { \
- ret = (os_hooks)->hook_interrupt(irq, opaque); \
- } \
- ret; \
- }) \
-
-#define V3_Yield(addr) \
- do { \
- extern struct v3_os_hooks * os_hooks; \
- if ((os_hooks) && (os_hooks)->yield_cpu) { \
- (os_hooks)->yield_cpu(); \
- } \
- } while (0) \
+#define V3_PAddr(addr) ({ \
+ extern struct v3_os_hooks * os_hooks; \
+ void * var = 0; \
+ if ((os_hooks) && (os_hooks)->vaddr_to_paddr) { \
+ var = (os_hooks)->vaddr_to_paddr(addr); \
+ } \
+ var; \
+ })
+#define V3_Malloc(size) ({ \
+ extern struct v3_os_hooks * os_hooks; \
+ void * var = 0; \
+ if ((os_hooks) && (os_hooks)->malloc) { \
+ var = (os_hooks)->malloc(size); \
+ } \
+ var; \
+ })
+// We need to check the hook structure at runtime to ensure its SAFE
+#define V3_Free(addr) \
+ do { \
+ extern struct v3_os_hooks * os_hooks; \
+ if ((os_hooks) && (os_hooks)->free) { \
+ (os_hooks)->free(addr); \
+ } \
+ } while (0)
+// uint_t V3_CPU_KHZ();
+#define V3_CPU_KHZ() ({ \
+ unsigned int khz = 0; \
+ extern struct v3_os_hooks * os_hooks; \
+ if ((os_hooks) && (os_hooks)->get_cpu_khz) { \
+ khz = (os_hooks)->get_cpu_khz(); \
+ } \
+ khz; \
+ }) \
+
+
+
+#define V3_Hook_Interrupt(irq, opaque) ({ \
+ int ret = 0; \
+ extern struct v3_os_hooks * os_hooks; \
+ if ((os_hooks) && (os_hooks)->hook_interrupt) { \
+ ret = (os_hooks)->hook_interrupt(irq, opaque); \
+ } \
+ ret; \
+ }) \
+
+#define V3_Yield(addr) \
+ do { \
+ extern struct v3_os_hooks * os_hooks; \
+ if ((os_hooks) && (os_hooks)->yield_cpu) { \
+ (os_hooks)->yield_cpu(); \
+ } \
+ } while (0) \
+ \
+ \
+ \
+ \
+ \
/* ** */
#define V3_ASSERT(x) \
- do { \
- if (!(x)) { \
- PrintDebug("Failed assertion in %s: %s at %s, line %d, RA=%lx\n", \
- __func__, #x, __FILE__, __LINE__, \
- (ulong_t) __builtin_return_address(0)); \
- while(1); \
- } \
- } while(0) \
-
-
-#define V3_REGISTER_PKT_DELIVERY(x) \
- ({\
- int ret = 0;\
- extern struct v3_os_hooks * os_hooks; \
- if ((os_hooks) && (os_hooks)->register_pkt_delivery) { \
- ret = (os_hooks)->register_pkt_delivery(x); \
- }\
- ret; \
- } )
-
-#define V3_SEND_PKT(x, y) \
- ({\
- int ret=0; \
- extern struct v3_os_hooks * os_hooks; \
- if ((os_hooks) && (os_hooks)->ne2k_send_packet) { \
- ret = (os_hooks)->ne2k_send_packet(x, y); \
- }\
- ret; \
- })
-
+ do { \
+ if (!(x)) { \
+ PrintDebug("Failed assertion in %s: %s at %s, line %d, RA=%lx\n", \
+ __func__, #x, __FILE__, __LINE__, \
+ (ulong_t) __builtin_return_address(0)); \
+ while(1); \
+ } \
+ } while(0) \
+
+
+#define V3_REGISTER_PKT_DELIVERY(x) ({ \
+ int ret = 0; \
+ extern struct v3_os_hooks * os_hooks; \
+ if ((os_hooks) && (os_hooks)->register_pkt_delivery) { \
+ ret = (os_hooks)->register_pkt_delivery(x); \
+ } \
+ ret; \
+ })
+
+#define V3_SEND_PKT(x, y) ({ \
+ int ret = 0; \
+ extern struct v3_os_hooks * os_hooks; \
+ if ((os_hooks) && (os_hooks)->ne2k_send_packet) { \
+ ret = (os_hooks)->ne2k_send_packet(x, y); \
+ } \
+ ret; \
+ })
+
#define VMM_INVALID_CPU 0
#define VMM_VMX_CPU 1
/* This will contain function pointers that provide OS services */
struct v3_os_hooks {
- void (*print_info)(const char * format, ...)
+ void (*print_info)(const char * format, ...)
__attribute__ ((format (printf, 1, 2)));
- void (*print_debug)(const char * format, ...)
+ void (*print_debug)(const char * format, ...)
__attribute__ ((format (printf, 1, 2)));
- void (*print_trace)(const char * format, ...)
+ void (*print_trace)(const char * format, ...)
__attribute__ ((format (printf, 1, 2)));
- void *(*allocate_pages)(int numPages);
- void (*free_page)(void * page);
+ void *(*allocate_pages)(int numPages);
+ void (*free_page)(void * page);
- void *(*malloc)(unsigned int size);
- void (*free)(void * addr);
+ void *(*malloc)(unsigned int size);
+ void (*free)(void * addr);
- void *(*paddr_to_vaddr)(void *addr);
- void *(*vaddr_to_paddr)(void *addr);
+ void *(*paddr_to_vaddr)(void *addr);
+ void *(*vaddr_to_paddr)(void *addr);
- // int (*hook_interrupt)(struct guest_info *s, int irq);
+ // int (*hook_interrupt)(struct guest_info *s, int irq);
- int (*hook_interrupt)(struct guest_info * vm, unsigned int irq);
+ int (*hook_interrupt)(struct guest_info * vm, unsigned int irq);
- int (*ack_irq)(int irq);
+ int (*ack_irq)(int irq);
- unsigned int (*get_cpu_khz)(void);
+ unsigned int (*get_cpu_khz)(void);
- void (*start_kernel_thread)(void); // include pointer to function
+ void (*start_kernel_thread)(void); // include pointer to function
- void (*yield_cpu)(void);
+ void (*yield_cpu)(void);
- //function by network card driver
- int (*register_pkt_delivery)(int (*rcvd_fn)(uchar_t *packet, uint_t size));
- int (*ne2k_send_packet)(uchar_t *packet, uint_t size);
+ //function by network card driver
+ int (*register_pkt_delivery)(int (*rcvd_fn)(uchar_t *packet, uint_t size));
+ int (*ne2k_send_packet)(uchar_t *packet, uint_t size);
};
struct v3_vm_config {
- void * rombios;
- int rombios_size;
+ void * rombios;
+ int rombios_size;
- void * vgabios;
- int vgabios_size;
+ void * vgabios;
+ int vgabios_size;
- unsigned long mem_size; // in bytes, var should be natural size of cpu
- // so we can specify maximum physical address size
- // (We're screwed if we want to do 32 bit host/64 bit guest)
+ unsigned long mem_size; // in bytes, var should be natural size of cpu
+ // so we can specify maximum physical address size
+ // (We're screwed if we want to do 32 bit host/64 bit guest)
- int enable_profiling;
+ int enable_profiling;
- int use_ramdisk;
- void * ramdisk;
- int ramdisk_size;
+ int use_ramdisk;
+ void * ramdisk;
+ int ramdisk_size;
};
/* This will contain Function pointers that control the VMs */
struct v3_ctrl_ops {
- struct guest_info *(*allocate_guest)(void);
+ struct guest_info *(*allocate_guest)(void);
- int (*config_guest)(struct guest_info * info, struct v3_vm_config * config_ptr);
- int (*init_guest)(struct guest_info * info);
- int (*start_guest)(struct guest_info * info);
- // int (*stop_vm)(uint_t vm_id);
+ int (*config_guest)(struct guest_info * info, struct v3_vm_config * config_ptr);
+ int (*init_guest)(struct guest_info * info);
+ int (*start_guest)(struct guest_info * info);
+ // int (*stop_vm)(uint_t vm_id);
- int (*has_nested_paging)(void);
+ int (*has_nested_paging)(void);
- // v3_cpu_arch_t (*get_cpu_arch)();
+ // v3_cpu_arch_t (*get_cpu_arch)();
};
// This is the interrupt state that the VMM's interrupt handlers need to see
//
struct v3_interrupt {
- unsigned int irq;
- unsigned int error;
+ unsigned int irq;
+ unsigned int error;
- unsigned int should_ack; // Should the vmm ack this interrupt, or will
- // the host OS do it?
+ unsigned int should_ack; // Should the vmm ack this interrupt, or will
+ // the host OS do it?
};
#include <palacios/vm_guest.h>
struct cr0_real {
- uint_t pe : 1;
- uint_t mp : 1;
- uint_t em : 1;
- uint_t ts : 1;
+ uint_t pe : 1;
+ uint_t mp : 1;
+ uint_t em : 1;
+ uint_t ts : 1;
} __attribute__((packed));
struct cr0_32 {
- uint_t pe : 1;
- uint_t mp : 1;
- uint_t em : 1;
- uint_t ts : 1;
- uint_t et : 1;
- uint_t ne : 1;
- uint_t rsvd1 : 10;
- uint_t wp : 1;
- uint_t rsvd2 : 1;
- uint_t am : 1;
- uint_t rsvd3 : 10;
- uint_t nw : 1;
- uint_t cd : 1;
- uint_t pg : 1;
+ uint_t pe : 1;
+ uint_t mp : 1;
+ uint_t em : 1;
+ uint_t ts : 1;
+ uint_t et : 1;
+ uint_t ne : 1;
+ uint_t rsvd1 : 10;
+ uint_t wp : 1;
+ uint_t rsvd2 : 1;
+ uint_t am : 1;
+ uint_t rsvd3 : 10;
+ uint_t nw : 1;
+ uint_t cd : 1;
+ uint_t pg : 1;
} __attribute__((packed));
struct cr0_64 {
- uint_t pe : 1;
- uint_t mp : 1;
- uint_t em : 1;
- uint_t ts : 1;
- uint_t et : 1;
- uint_t ne : 1;
- uint_t rsvd1 : 10;
- uint_t wp : 1;
- uint_t rsvd2 : 1;
- uint_t am : 1;
- uint_t rsvd3 : 10;
- uint_t nw : 1;
- uint_t cd : 1;
- uint_t pg : 1;
-
- uint_t rsvd4; // MBZ
+ uint_t pe : 1;
+ uint_t mp : 1;
+ uint_t em : 1;
+ uint_t ts : 1;
+ uint_t et : 1;
+ uint_t ne : 1;
+ uint_t rsvd1 : 10;
+ uint_t wp : 1;
+ uint_t rsvd2 : 1;
+ uint_t am : 1;
+ uint_t rsvd3 : 10;
+ uint_t nw : 1;
+ uint_t cd : 1;
+ uint_t pg : 1;
+
+ uint_t rsvd4; // MBZ
} __attribute__((packed));
struct cr2_32 {
- uint_t pf_vaddr;
+ uint_t pf_vaddr;
} __attribute__((packed));
struct cr2_64 {
- ullong_t pf_vaddr;
+ ullong_t pf_vaddr;
} __attribute__((packed));
struct cr3_32 {
- uint_t rsvd1 : 3;
- uint_t pwt : 1;
- uint_t pcd : 1;
- uint_t rsvd2 : 7;
- uint_t pdt_base_addr : 20;
+ uint_t rsvd1 : 3;
+ uint_t pwt : 1;
+ uint_t pcd : 1;
+ uint_t rsvd2 : 7;
+ uint_t pdt_base_addr : 20;
} __attribute__((packed));
struct cr3_32_PAE {
- uint_t rsvd1 : 3;
- uint_t pwt : 1;
- uint_t pcd : 1;
- uint_t pdpt_base_addr : 27;
+ uint_t rsvd1 : 3;
+ uint_t pwt : 1;
+ uint_t pcd : 1;
+ uint_t pdpt_base_addr : 27;
} __attribute__((packed));
struct cr3_64 {
- uint_t rsvd1 : 3;
- uint_t pwt : 1;
- uint_t pcd : 1;
- uint_t rsvd2 : 7;
- ullong_t pml4t_base_addr : 40;
- uint_t rsvd3 : 12;
+ uint_t rsvd1 : 3;
+ uint_t pwt : 1;
+ uint_t pcd : 1;
+ uint_t rsvd2 : 7;
+ ullong_t pml4t_base_addr : 40;
+ uint_t rsvd3 : 12;
} __attribute__((packed));
struct cr4_32 {
- uint_t vme : 1;
- uint_t pvi : 1;
- uint_t tsd : 1;
- uint_t de : 1;
- uint_t pse : 1;
- uint_t pae : 1;
- uint_t mce : 1;
- uint_t pge : 1;
- uint_t pce : 1;
- uint_t osf_xsr : 1;
- uint_t osx : 1;
- uint_t rsvd1 : 21;
+ uint_t vme : 1;
+ uint_t pvi : 1;
+ uint_t tsd : 1;
+ uint_t de : 1;
+ uint_t pse : 1;
+ uint_t pae : 1;
+ uint_t mce : 1;
+ uint_t pge : 1;
+ uint_t pce : 1;
+ uint_t osf_xsr : 1;
+ uint_t osx : 1;
+ uint_t rsvd1 : 21;
} __attribute__((packed));
struct cr4_64 {
- uint_t vme : 1;
- uint_t pvi : 1;
- uint_t tsd : 1;
- uint_t de : 1;
- uint_t pse : 1;
- uint_t pae : 1;
- uint_t mce : 1;
- uint_t pge : 1;
- uint_t pce : 1;
- uint_t osf_xsr : 1;
- uint_t osx : 1;
- uint_t rsvd1 : 21;
- uint_t rsvd2 : 32;
+ uint_t vme : 1;
+ uint_t pvi : 1;
+ uint_t tsd : 1;
+ uint_t de : 1;
+ uint_t pse : 1;
+ uint_t pae : 1;
+ uint_t mce : 1;
+ uint_t pge : 1;
+ uint_t pce : 1;
+ uint_t osf_xsr : 1;
+ uint_t osx : 1;
+ uint_t rsvd1 : 21;
+ uint_t rsvd2 : 32;
} __attribute__((packed));
struct efer_64 {
- uint_t sce : 1;
- uint_t rsvd1 : 7; // RAZ
- uint_t lme : 1;
- uint_t rsvd2 : 1; // MBZ
- uint_t lma : 1;
- uint_t nxe : 1;
- uint_t svme : 1;
- uint_t rsvd3 : 1; // MBZ
- uint_t ffxsr : 1;
- uint_t rsvd4 : 12; // MBZ
- uint_t rsvd5 : 32; // MBZ
+ uint_t sce : 1;
+ uint_t rsvd1 : 7; // RAZ
+ uint_t lme : 1;
+ uint_t rsvd2 : 1; // MBZ
+ uint_t lma : 1;
+ uint_t nxe : 1;
+ uint_t svme : 1;
+ uint_t rsvd3 : 1; // MBZ
+ uint_t ffxsr : 1;
+ uint_t rsvd4 : 12; // MBZ
+ uint_t rsvd5 : 32; // MBZ
} __attribute__((packed));
struct rflags {
- uint_t cf : 1; // carry flag
- uint_t rsvd1 : 1; // Must be 1
- uint_t pf : 1; // parity flag
- uint_t rsvd2 : 1; // Read as 0
- uint_t af : 1; // Auxillary flag
- uint_t rsvd3 : 1; // Read as 0
- uint_t zf : 1; // zero flag
- uint_t sf : 1; // sign flag
- uint_t tf : 1; // trap flag
- uint_t intr : 1; // interrupt flag
- uint_t df : 1; // direction flag
- uint_t of : 1; // overflow flag
- uint_t iopl : 2; // IO privilege level
- uint_t nt : 1; // nested task
- uint_t rsvd4 : 1; // read as 0
- uint_t rf : 1; // resume flag
- uint_t vm : 1; // Virtual-8086 mode
- uint_t ac : 1; // alignment check
- uint_t vif : 1; // virtual interrupt flag
- uint_t vip : 1; // virtual interrupt pending
- uint_t id : 1; // ID flag
- uint_t rsvd5 : 10; // Read as 0
- uint_t rsvd6 : 32; // Read as 0
+ uint_t cf : 1; // carry flag
+ uint_t rsvd1 : 1; // Must be 1
+ uint_t pf : 1; // parity flag
+ uint_t rsvd2 : 1; // Read as 0
+ uint_t af : 1; // Auxillary flag
+ uint_t rsvd3 : 1; // Read as 0
+ uint_t zf : 1; // zero flag
+ uint_t sf : 1; // sign flag
+ uint_t tf : 1; // trap flag
+ uint_t intr : 1; // interrupt flag
+ uint_t df : 1; // direction flag
+ uint_t of : 1; // overflow flag
+ uint_t iopl : 2; // IO privilege level
+ uint_t nt : 1; // nested task
+ uint_t rsvd4 : 1; // read as 0
+ uint_t rf : 1; // resume flag
+ uint_t vm : 1; // Virtual-8086 mode
+ uint_t ac : 1; // alignment check
+ uint_t vif : 1; // virtual interrupt flag
+ uint_t vip : 1; // virtual interrupt pending
+ uint_t id : 1; // ID flag
+ uint_t rsvd5 : 10; // Read as 0
+ uint_t rsvd6 : 32; // Read as 0
} __attribute__((packed));
#include <palacios/vmm.h>
struct dbg_bp32 {
- uint_t breakpoint : 32;
+ uint_t breakpoint : 32;
};
struct dbg_bp64 {
- ullong_t breakpoint;
+ ullong_t breakpoint;
};
struct dr6_32 {
- uint_t bp0 : 1;
- uint_t bp1 : 1;
- uint_t bp2 : 1;
- uint_t bp3 : 1;
- uint_t rsvd1 : 8; // read as ones
- uint_t rsvd2 : 1; // read as zero
- uint_t bd : 1;
- uint_t bs : 1;
- uint_t bt : 1;
- uint_t rsvd3 : 16; // read as one
+ uint_t bp0 : 1;
+ uint_t bp1 : 1;
+ uint_t bp2 : 1;
+ uint_t bp3 : 1;
+ uint_t rsvd1 : 8; // read as ones
+ uint_t rsvd2 : 1; // read as zero
+ uint_t bd : 1;
+ uint_t bs : 1;
+ uint_t bt : 1;
+ uint_t rsvd3 : 16; // read as one
};
struct dr6_64 {
- uint_t bp0 : 1;
- uint_t bp1 : 1;
- uint_t bp2 : 1;
- uint_t bp3 : 1;
- uint_t rsvd1 : 8; // read as ones
- uint_t rsvd2 : 1; // read as zero
- uint_t bd : 1;
- uint_t bs : 1;
- uint_t bt : 1;
- uint_t rsvd3 : 16; // read as one
- uint_t rsvd4 : 32; // MBZ
+ uint_t bp0 : 1;
+ uint_t bp1 : 1;
+ uint_t bp2 : 1;
+ uint_t bp3 : 1;
+ uint_t rsvd1 : 8; // read as ones
+ uint_t rsvd2 : 1; // read as zero
+ uint_t bd : 1;
+ uint_t bs : 1;
+ uint_t bt : 1;
+ uint_t rsvd3 : 16; // read as one
+ uint_t rsvd4 : 32; // MBZ
};
struct dr7_32 {
- uint_t L0 : 1;
- uint_t G0 : 1;
- uint_t L1 : 1;
- uint_t G1 : 1;
- uint_t L2 : 1;
- uint_t G2 : 1;
- uint_t L3 : 1;
- uint_t G3 : 1;
- uint_t LE : 1;
- uint_t GE : 1;
- uint_t rsvd1 : 1; // Read as one
- uint_t rsvd2 : 2; // Read as zero
- uint_t GD : 1;
- uint_t rsvd3 : 2; // Read as zero
- uint_t rw0 : 1;
- uint_t len0 : 1;
- uint_t rw1 : 1;
- uint_t len1 : 1;
- uint_t rw2 : 1;
- uint_t len2 : 1;
- uint_t rw3 : 1;
- uint_t len3 : 1;
+ uint_t L0 : 1;
+ uint_t G0 : 1;
+ uint_t L1 : 1;
+ uint_t G1 : 1;
+ uint_t L2 : 1;
+ uint_t G2 : 1;
+ uint_t L3 : 1;
+ uint_t G3 : 1;
+ uint_t LE : 1;
+ uint_t GE : 1;
+ uint_t rsvd1 : 1; // Read as one
+ uint_t rsvd2 : 2; // Read as zero
+ uint_t GD : 1;
+ uint_t rsvd3 : 2; // Read as zero
+ uint_t rw0 : 1;
+ uint_t len0 : 1;
+ uint_t rw1 : 1;
+ uint_t len1 : 1;
+ uint_t rw2 : 1;
+ uint_t len2 : 1;
+ uint_t rw3 : 1;
+ uint_t len3 : 1;
};
struct dr7_64 {
- uint_t L0 : 1;
- uint_t G0 : 1;
- uint_t L1 : 1;
- uint_t G1 : 1;
- uint_t L2 : 1;
- uint_t G2 : 1;
- uint_t L3 : 1;
- uint_t G3 : 1;
- uint_t LE : 1;
- uint_t GE : 1;
- uint_t rsvd1 : 1; // Read as one
- uint_t rsvd2 : 2; // Read as zero
- uint_t GD : 1;
- uint_t rsvd3 : 2; // Read as zero
- uint_t rw0 : 1;
- uint_t len0 : 1;
- uint_t rw1 : 1;
- uint_t len1 : 1;
- uint_t rw2 : 1;
- uint_t len2 : 1;
- uint_t rw3 : 1;
- uint_t len3 : 1;
- uint_t rsvd4 : 32; // MBZ
+ uint_t L0 : 1;
+ uint_t G0 : 1;
+ uint_t L1 : 1;
+ uint_t G1 : 1;
+ uint_t L2 : 1;
+ uint_t G2 : 1;
+ uint_t L3 : 1;
+ uint_t G3 : 1;
+ uint_t LE : 1;
+ uint_t GE : 1;
+ uint_t rsvd1 : 1; // Read as one
+ uint_t rsvd2 : 2; // Read as zero
+ uint_t GD : 1;
+ uint_t rsvd3 : 2; // Read as zero
+ uint_t rw0 : 1;
+ uint_t len0 : 1;
+ uint_t rw1 : 1;
+ uint_t len1 : 1;
+ uint_t rw2 : 1;
+ uint_t len2 : 1;
+ uint_t rw3 : 1;
+ uint_t len3 : 1;
+ uint_t rsvd4 : 32; // MBZ
};
typedef enum {INVALID_OPERAND, REG_OPERAND, MEM_OPERAND, IMM_OPERAND} v3_operand_type_t;
struct x86_operand {
- addr_t operand;
- uint_t size;
- v3_operand_type_t type;
+ addr_t operand;
+ uint_t size;
+ v3_operand_type_t type;
};
struct x86_prefixes {
- uint_t lock : 1; // 0xF0
- uint_t repne : 1; // 0xF2
- uint_t repnz : 1; // 0xF2
- uint_t rep : 1; // 0xF3
- uint_t repe : 1; // 0xF3
- uint_t repz : 1; // 0xF3
- uint_t cs_override : 1; // 0x2E
- uint_t ss_override : 1; // 0x36
- uint_t ds_override : 1; // 0x3E
- uint_t es_override : 1; // 0x26
- uint_t fs_override : 1; // 0x64
- uint_t gs_override : 1; // 0x65
- uint_t br_not_taken : 1; // 0x2E
- uint_t br_taken : 1; // 0x3E
- uint_t op_size : 1; // 0x66
- uint_t addr_size : 1; // 0x67
+ uint_t lock : 1; // 0xF0
+ uint_t repne : 1; // 0xF2
+ uint_t repnz : 1; // 0xF2
+ uint_t rep : 1; // 0xF3
+ uint_t repe : 1; // 0xF3
+ uint_t repz : 1; // 0xF3
+ uint_t cs_override : 1; // 0x2E
+ uint_t ss_override : 1; // 0x36
+ uint_t ds_override : 1; // 0x3E
+ uint_t es_override : 1; // 0x26
+ uint_t fs_override : 1; // 0x64
+ uint_t gs_override : 1; // 0x65
+ uint_t br_not_taken : 1; // 0x2E
+ uint_t br_taken : 1; // 0x3E
+ uint_t op_size : 1; // 0x66
+ uint_t addr_size : 1; // 0x67
};
struct x86_instr {
- struct x86_prefixes prefixes;
- uint_t instr_length;
- v3_op_type_t op_type;
- uint_t num_operands;
- struct x86_operand dst_operand;
- struct x86_operand src_operand;
- struct x86_operand third_operand;
- addr_t str_op_length;
- addr_t is_str_op;
- void * decoder_data;
+ struct x86_prefixes prefixes;
+ uint_t instr_length;
+ v3_op_type_t op_type;
+ uint_t num_operands;
+ struct x86_operand dst_operand;
+ struct x86_operand src_operand;
+ struct x86_operand third_operand;
+ addr_t str_op_length;
+ addr_t is_str_op;
+ void * decoder_data;
};
struct basic_instr_info {
- uint_t instr_length;
- uint_t op_size;
- uint_t str_op : 1;
- uint_t has_rep : 1;
+ uint_t instr_length;
+ uint_t op_size;
+ uint_t str_op : 1;
+ uint_t has_rep : 1;
};
- /************************/
- /* EXTERNAL DECODER API */
+/************************/
+/* EXTERNAL DECODER API */
/************************/
/*
This is an External API definition that must be implemented by a decoder
#define MODRM_RM(x) (x & 0x7)
struct modrm_byte {
- uint_t rm : 3 PACKED;
- uint_t reg : 3 PACKED;
- uint_t mod : 2 PACKED;
+ uint_t rm : 3 PACKED;
+ uint_t reg : 3 PACKED;
+ uint_t mod : 2 PACKED;
};
#define SIB_SCALE(x) (x & 0x7)
struct sib_byte {
- uint_t base : 3 PACKED;
- uint_t index : 3 PACKED;
- uint_t scale : 2 PACKED;
+ uint_t base : 3 PACKED;
+ uint_t index : 3 PACKED;
+ uint_t scale : 2 PACKED;
};
static inline int is_prefix_byte(uchar_t byte) {
- switch (byte) {
- case 0xF0: // lock
- case 0xF2: // REPNE/REPNZ
- case 0xF3: // REP or REPE/REPZ
- case 0x2E: // CS override or Branch hint not taken (with Jcc instrs)
- case 0x36: // SS override
- case 0x3E: // DS override or Branch hint taken (with Jcc instrs)
- case 0x26: // ES override
- case 0x64: // FS override
- case 0x65: // GS override
- //case 0x2E: // branch not taken hint
- // case 0x3E: // branch taken hint
- case 0x66: // operand size override
- case 0x67: // address size override
- return 1;
- break;
- default:
- return 0;
- break;
- }
+ switch (byte) {
+ case 0xF0: // lock
+ case 0xF2: // REPNE/REPNZ
+ case 0xF3: // REP or REPE/REPZ
+ case 0x2E: // CS override or Branch hint not taken (with Jcc instrs)
+ case 0x36: // SS override
+ case 0x3E: // DS override or Branch hint taken (with Jcc instrs)
+ case 0x26: // ES override
+ case 0x64: // FS override
+ case 0x65: // GS override
+ //case 0x2E: // branch not taken hint
+ // case 0x3E: // branch taken hint
+ case 0x66: // operand size override
+ case 0x67: // address size override
+ return 1;
+ break;
+ default:
+ return 0;
+ break;
+ }
}
static inline v3_reg_t get_gpr_mask(struct guest_info * info) {
- switch (info->cpu_mode) {
- case REAL:
- return 0xffff;
- break;
- case PROTECTED:
- case PROTECTED_PAE:
- return 0xffffffff;
- case LONG:
- case LONG_32_COMPAT:
- case LONG_16_COMPAT:
- default:
- PrintError("Unsupported Address Mode\n");
- return -1;
- }
+ switch (info->cpu_mode) {
+ case REAL:
+ return 0xffff;
+ break;
+ case PROTECTED:
+ case PROTECTED_PAE:
+ return 0xffffffff;
+ case LONG:
+ case LONG_32_COMPAT:
+ case LONG_16_COMPAT:
+ default:
+ PrintError("Unsupported Address Mode\n");
+ return -1;
+ }
}
static inline addr_t get_addr_linear(struct guest_info * info, addr_t addr, struct v3_segment * seg) {
- switch (info->cpu_mode) {
- case REAL:
- // It appears that the segment values are computed and cached in the vmcb structure
- // We Need to check this for Intel
- /* return addr + (seg->selector << 4);
- break;*/
-
- case PROTECTED:
- case PROTECTED_PAE:
- case LONG_32_COMPAT:
- return addr + seg->base;
- break;
-
- case LONG:
- // In long mode the segment bases are disregarded (forced to 0), unless using
- // FS or GS, then the base addresses are added
- return addr + seg->base;
-
- case LONG_16_COMPAT:
- default:
- PrintError("Unsupported CPU Mode: %d\n", info->cpu_mode);
- return -1;
- }
+ switch (info->cpu_mode) {
+ case REAL:
+ // It appears that the segment values are computed and cached in the vmcb structure
+ // We Need to check this for Intel
+ /* return addr + (seg->selector << 4);
+ break;*/
+
+ case PROTECTED:
+ case PROTECTED_PAE:
+ case LONG_32_COMPAT:
+ return addr + seg->base;
+ break;
+
+ case LONG:
+ // In long mode the segment bases are disregarded (forced to 0), unless using
+ // FS or GS, then the base addresses are added
+ return addr + seg->base;
+
+ case LONG_16_COMPAT:
+ default:
+ PrintError("Unsupported CPU Mode: %d\n", info->cpu_mode);
+ return -1;
+ }
}
struct v3_gprs;
static inline addr_t decode_register(struct v3_gprs * gprs, char reg_code, reg_size_t reg_size) {
- addr_t reg_addr;
-
- switch (reg_code) {
- case 0:
- reg_addr = (addr_t)&(gprs->rax);
- break;
- case 1:
- reg_addr = (addr_t)&(gprs->rcx);
- break;
- case 2:
- reg_addr = (addr_t)&(gprs->rdx);
- break;
- case 3:
- reg_addr = (addr_t)&(gprs->rbx);
- break;
- case 4:
- if (reg_size == REG8) {
- reg_addr = (addr_t)&(gprs->rax) + 1;
- } else {
- reg_addr = (addr_t)&(gprs->rsp);
- }
- break;
- case 5:
- if (reg_size == REG8) {
- reg_addr = (addr_t)&(gprs->rcx) + 1;
- } else {
- reg_addr = (addr_t)&(gprs->rbp);
+ addr_t reg_addr;
+
+ switch (reg_code) {
+ case 0:
+ reg_addr = (addr_t)&(gprs->rax);
+ break;
+ case 1:
+ reg_addr = (addr_t)&(gprs->rcx);
+ break;
+ case 2:
+ reg_addr = (addr_t)&(gprs->rdx);
+ break;
+ case 3:
+ reg_addr = (addr_t)&(gprs->rbx);
+ break;
+ case 4:
+ if (reg_size == REG8) {
+ reg_addr = (addr_t)&(gprs->rax) + 1;
+ } else {
+ reg_addr = (addr_t)&(gprs->rsp);
+ }
+ break;
+ case 5:
+ if (reg_size == REG8) {
+ reg_addr = (addr_t)&(gprs->rcx) + 1;
+ } else {
+ reg_addr = (addr_t)&(gprs->rbp);
+ }
+ break;
+ case 6:
+ if (reg_size == REG8) {
+ reg_addr = (addr_t)&(gprs->rdx) + 1;
+ } else {
+ reg_addr = (addr_t)&(gprs->rsi);
+ }
+ break;
+ case 7:
+ if (reg_size == REG8) {
+ reg_addr = (addr_t)&(gprs->rbx) + 1;
+ } else {
+ reg_addr = (addr_t)&(gprs->rdi);
+ }
+ break;
+ default:
+ reg_addr = 0;
+ break;
}
- break;
- case 6:
- if (reg_size == REG8) {
- reg_addr = (addr_t)&(gprs->rdx) + 1;
- } else {
- reg_addr = (addr_t)&(gprs->rsi);
- }
- break;
- case 7:
- if (reg_size == REG8) {
- reg_addr = (addr_t)&(gprs->rbx) + 1;
- } else {
- reg_addr = (addr_t)&(gprs->rdi);
- }
- break;
- default:
- reg_addr = 0;
- break;
- }
- return reg_addr;
+ return reg_addr;
}
static inline v3_operand_type_t decode_operands16(struct v3_gprs * gprs, // input/output
- char * modrm_instr, // input
- int * offset, // output
- addr_t * first_operand, // output
- addr_t * second_operand, // output
- reg_size_t reg_size) { // input
+ char * modrm_instr, // input
+ int * offset, // output
+ addr_t * first_operand, // output
+ addr_t * second_operand, // output
+ reg_size_t reg_size) { // input
- struct modrm_byte * modrm = (struct modrm_byte *)modrm_instr;
- addr_t base_addr = 0;
- modrm_mode_t mod_mode = 0;
- v3_operand_type_t addr_type = INVALID_OPERAND;
- char * instr_cursor = modrm_instr;
+ struct modrm_byte * modrm = (struct modrm_byte *)modrm_instr;
+ addr_t base_addr = 0;
+ modrm_mode_t mod_mode = 0;
+ v3_operand_type_t addr_type = INVALID_OPERAND;
+ char * instr_cursor = modrm_instr;
- // PrintDebug("ModRM mod=%d\n", modrm->mod);
+ // PrintDebug("ModRM mod=%d\n", modrm->mod);
- instr_cursor += 1;
+ instr_cursor += 1;
- if (modrm->mod == 3) {
- mod_mode = REG;
- addr_type = REG_OPERAND;
- //PrintDebug("first operand = Register (RM=%d)\n",modrm->rm);
+ if (modrm->mod == 3) {
+ mod_mode = REG;
+ addr_type = REG_OPERAND;
+ //PrintDebug("first operand = Register (RM=%d)\n",modrm->rm);
- *first_operand = decode_register(gprs, modrm->rm, reg_size);
+ *first_operand = decode_register(gprs, modrm->rm, reg_size);
- } else {
+ } else {
- addr_type = MEM_OPERAND;
+ addr_type = MEM_OPERAND;
- if (modrm->mod == 0) {
- mod_mode = DISP0;
- } else if (modrm->mod == 1) {
- mod_mode = DISP8;
- } else if (modrm->mod == 2) {
- mod_mode = DISP16;
- }
+ if (modrm->mod == 0) {
+ mod_mode = DISP0;
+ } else if (modrm->mod == 1) {
+ mod_mode = DISP8;
+ } else if (modrm->mod == 2) {
+ mod_mode = DISP16;
+ }
- switch (modrm->rm) {
- case 0:
- base_addr = gprs->rbx + gprs->rsi;
- break;
- case 1:
- base_addr = gprs->rbx + gprs->rdi;
- break;
- case 2:
- base_addr = gprs->rbp + gprs->rsi;
- break;
- case 3:
- base_addr = gprs->rbp + gprs->rdi;
- break;
- case 4:
- base_addr = gprs->rsi;
- break;
- case 5:
- base_addr = gprs->rdi;
- break;
- case 6:
- if (modrm->mod == 0) {
- base_addr = 0;
- mod_mode = DISP16;
- } else {
- base_addr = gprs->rbp;
- }
- break;
- case 7:
- base_addr = gprs->rbx;
- break;
- }
+ switch (modrm->rm) {
+ case 0:
+ base_addr = gprs->rbx + gprs->rsi;
+ break;
+ case 1:
+ base_addr = gprs->rbx + gprs->rdi;
+ break;
+ case 2:
+ base_addr = gprs->rbp + gprs->rsi;
+ break;
+ case 3:
+ base_addr = gprs->rbp + gprs->rdi;
+ break;
+ case 4:
+ base_addr = gprs->rsi;
+ break;
+ case 5:
+ base_addr = gprs->rdi;
+ break;
+ case 6:
+ if (modrm->mod == 0) {
+ base_addr = 0;
+ mod_mode = DISP16;
+ } else {
+ base_addr = gprs->rbp;
+ }
+ break;
+ case 7:
+ base_addr = gprs->rbx;
+ break;
+ }
- if (mod_mode == DISP8) {
- base_addr += (uchar_t)*(instr_cursor);
- instr_cursor += 1;
- } else if (mod_mode == DISP16) {
- base_addr += (ushort_t)*(instr_cursor);
- instr_cursor += 2;
- }
+ if (mod_mode == DISP8) {
+ base_addr += (uchar_t)*(instr_cursor);
+ instr_cursor += 1;
+ } else if (mod_mode == DISP16) {
+ base_addr += (ushort_t)*(instr_cursor);
+ instr_cursor += 2;
+ }
- *first_operand = base_addr;
- }
+ *first_operand = base_addr;
+ }
- *offset += (instr_cursor - modrm_instr);
- *second_operand = decode_register(gprs, modrm->reg, reg_size);
+ *offset += (instr_cursor - modrm_instr);
+ *second_operand = decode_register(gprs, modrm->reg, reg_size);
- return addr_type;
+ return addr_type;
}
static inline v3_operand_type_t decode_operands32(struct v3_gprs * gprs, // input/output
- uchar_t * modrm_instr, // input
- int * offset, // output
- addr_t * first_operand, // output
- addr_t * second_operand, // output
- reg_size_t reg_size) { // input
+ uchar_t * modrm_instr, // input
+ int * offset, // output
+ addr_t * first_operand, // output
+ addr_t * second_operand, // output
+ reg_size_t reg_size) { // input
- uchar_t * instr_cursor = modrm_instr;
- struct modrm_byte * modrm = (struct modrm_byte *)modrm_instr;
- addr_t base_addr = 0;
- modrm_mode_t mod_mode = 0;
- uint_t has_sib_byte = 0;
- v3_operand_type_t addr_type = INVALID_OPERAND;
+ uchar_t * instr_cursor = modrm_instr;
+ struct modrm_byte * modrm = (struct modrm_byte *)modrm_instr;
+ addr_t base_addr = 0;
+ modrm_mode_t mod_mode = 0;
+ uint_t has_sib_byte = 0;
+ v3_operand_type_t addr_type = INVALID_OPERAND;
- instr_cursor += 1;
+ instr_cursor += 1;
- if (modrm->mod == 3) {
- mod_mode = REG;
- addr_type = REG_OPERAND;
+ if (modrm->mod == 3) {
+ mod_mode = REG;
+ addr_type = REG_OPERAND;
- // PrintDebug("first operand = Register (RM=%d)\n",modrm->rm);
+ // PrintDebug("first operand = Register (RM=%d)\n",modrm->rm);
- *first_operand = decode_register(gprs, modrm->rm, reg_size);
+ *first_operand = decode_register(gprs, modrm->rm, reg_size);
- } else {
+ } else {
- addr_type = MEM_OPERAND;
+ addr_type = MEM_OPERAND;
- if (modrm->mod == 0) {
- mod_mode = DISP0;
- } else if (modrm->mod == 1) {
- mod_mode = DISP8;
- } else if (modrm->mod == 2) {
- mod_mode = DISP32;
- }
+ if (modrm->mod == 0) {
+ mod_mode = DISP0;
+ } else if (modrm->mod == 1) {
+ mod_mode = DISP8;
+ } else if (modrm->mod == 2) {
+ mod_mode = DISP32;
+ }
- switch (modrm->rm) {
- case 0:
- base_addr = gprs->rax;
- break;
- case 1:
- base_addr = gprs->rcx;
- break;
- case 2:
- base_addr = gprs->rdx;
- break;
- case 3:
- base_addr = gprs->rbx;
- break;
- case 4:
- has_sib_byte = 1;
- break;
- case 5:
- if (modrm->mod == 0) {
- base_addr = 0;
- mod_mode = DISP32;
- } else {
- base_addr = gprs->rbp;
- }
- break;
- case 6:
- base_addr = gprs->rsi;
- break;
- case 7:
- base_addr = gprs->rdi;
- break;
- }
+ switch (modrm->rm) {
+ case 0:
+ base_addr = gprs->rax;
+ break;
+ case 1:
+ base_addr = gprs->rcx;
+ break;
+ case 2:
+ base_addr = gprs->rdx;
+ break;
+ case 3:
+ base_addr = gprs->rbx;
+ break;
+ case 4:
+ has_sib_byte = 1;
+ break;
+ case 5:
+ if (modrm->mod == 0) {
+ base_addr = 0;
+ mod_mode = DISP32;
+ } else {
+ base_addr = gprs->rbp;
+ }
+ break;
+ case 6:
+ base_addr = gprs->rsi;
+ break;
+ case 7:
+ base_addr = gprs->rdi;
+ break;
+ }
- if (has_sib_byte) {
- instr_cursor += 1;
- struct sib_byte * sib = (struct sib_byte *)(instr_cursor);
- int scale = 1;
-
- instr_cursor += 1;
-
-
- if (sib->scale == 1) {
- scale = 2;
- } else if (sib->scale == 2) {
- scale = 4;
- } else if (sib->scale == 3) {
- scale = 8;
- }
-
-
- switch (sib->index) {
- case 0:
- base_addr = gprs->rax;
- break;
- case 1:
- base_addr = gprs->rcx;
- break;
- case 2:
- base_addr = gprs->rdx;
- break;
- case 3:
- base_addr = gprs->rbx;
- break;
- case 4:
- base_addr = 0;
- break;
- case 5:
- base_addr = gprs->rbp;
- break;
- case 6:
- base_addr = gprs->rsi;
- break;
- case 7:
- base_addr = gprs->rdi;
- break;
- }
-
- base_addr *= scale;
-
-
- switch (sib->base) {
- case 0:
- base_addr += gprs->rax;
- break;
- case 1:
- base_addr += gprs->rcx;
- break;
- case 2:
- base_addr += gprs->rdx;
- break;
- case 3:
- base_addr += gprs->rbx;
- break;
- case 4:
- base_addr += gprs->rsp;
- break;
- case 5:
- if (modrm->mod != 0) {
- base_addr += gprs->rbp;
+ if (has_sib_byte) {
+ instr_cursor += 1;
+ struct sib_byte * sib = (struct sib_byte *)(instr_cursor);
+ int scale = 1;
+
+ instr_cursor += 1;
+
+
+ if (sib->scale == 1) {
+ scale = 2;
+ } else if (sib->scale == 2) {
+ scale = 4;
+ } else if (sib->scale == 3) {
+ scale = 8;
+ }
+
+
+ switch (sib->index) {
+ case 0:
+ base_addr = gprs->rax;
+ break;
+ case 1:
+ base_addr = gprs->rcx;
+ break;
+ case 2:
+ base_addr = gprs->rdx;
+ break;
+ case 3:
+ base_addr = gprs->rbx;
+ break;
+ case 4:
+ base_addr = 0;
+ break;
+ case 5:
+ base_addr = gprs->rbp;
+ break;
+ case 6:
+ base_addr = gprs->rsi;
+ break;
+ case 7:
+ base_addr = gprs->rdi;
+ break;
+ }
+
+ base_addr *= scale;
+
+
+ switch (sib->base) {
+ case 0:
+ base_addr += gprs->rax;
+ break;
+ case 1:
+ base_addr += gprs->rcx;
+ break;
+ case 2:
+ base_addr += gprs->rdx;
+ break;
+ case 3:
+ base_addr += gprs->rbx;
+ break;
+ case 4:
+ base_addr += gprs->rsp;
+ break;
+ case 5:
+ if (modrm->mod != 0) {
+ base_addr += gprs->rbp;
+ }
+ break;
+ case 6:
+ base_addr += gprs->rsi;
+ break;
+ case 7:
+ base_addr += gprs->rdi;
+ break;
+ }
+
+ }
+
+
+ if (mod_mode == DISP8) {
+ base_addr += (uchar_t)*(instr_cursor);
+ instr_cursor += 1;
+ } else if (mod_mode == DISP32) {
+ base_addr += (uint_t)*(instr_cursor);
+ instr_cursor += 4;
}
- break;
- case 6:
- base_addr += gprs->rsi;
- break;
- case 7:
- base_addr += gprs->rdi;
- break;
- }
-
- }
-
-
- if (mod_mode == DISP8) {
- base_addr += (uchar_t)*(instr_cursor);
- instr_cursor += 1;
- } else if (mod_mode == DISP32) {
- base_addr += (uint_t)*(instr_cursor);
- instr_cursor += 4;
- }
- *first_operand = base_addr;
- }
+ *first_operand = base_addr;
+ }
- *offset += (instr_cursor - modrm_instr);
+ *offset += (instr_cursor - modrm_instr);
- *second_operand = decode_register(gprs, modrm->reg, reg_size);
+ *second_operand = decode_register(gprs, modrm->reg, reg_size);
- return addr_type;
+ return addr_type;
}
struct vmm_dev_mgr {
- uint_t num_devs;
- struct list_head dev_list;
+ uint_t num_devs;
+ struct list_head dev_list;
- uint_t num_io_hooks;
- struct list_head io_hooks;
+ uint_t num_io_hooks;
+ struct list_head io_hooks;
- uint_t num_mem_hooks;
- struct list_head mem_hooks;
+ uint_t num_mem_hooks;
+ struct list_head mem_hooks;
- uint_t num_msr_hook;
- struct list_head msr_hooks;
+ uint_t num_msr_hook;
+ struct list_head msr_hooks;
};
struct dev_io_hook {
- ushort_t port;
+ ushort_t port;
- int (*read)(ushort_t port, void * dst, uint_t length, struct vm_device * dev);
- int (*write)(ushort_t port, void * src, uint_t length, struct vm_device * dev);
+ int (*read)(ushort_t port, void * dst, uint_t length, struct vm_device * dev);
+ int (*write)(ushort_t port, void * src, uint_t length, struct vm_device * dev);
- struct vm_device * dev;
+ struct vm_device * dev;
- // Do not touch anything below this
+ // Do not touch anything below this
- struct list_head dev_list;
- struct list_head mgr_list;
+ struct list_head dev_list;
+ struct list_head mgr_list;
};
struct dev_mem_hook {
- void *addr_start;
- void *addr_end;
+ void *addr_start;
+ void *addr_end;
- struct vm_device * dev;
+ struct vm_device * dev;
- // Do not touch anything below this
- struct list_head dev_list;
- struct list_head mgr_list;
+ // Do not touch anything below this
+ struct list_head dev_list;
+ struct list_head mgr_list;
};
int v3_emulate_write_op(struct guest_info * info, addr_t write_gva, addr_t write_gpa, addr_t dst_addr,
- int (*write_fn)(addr_t guest_addr, void * src, uint_t length, void * priv_data),
- void * priv_data);
+ int (*write_fn)(addr_t guest_addr, void * src, uint_t length, void * priv_data),
+ void * priv_data);
int v3_emulate_read_op(struct guest_info * info, addr_t read_gva, addr_t read_gpa, addr_t src_addr,
int (*read_fn)(addr_t guest_addr, void * dst, uint_t length, void * priv_data),
#define DEFINE_HASHTABLE_INSERT(fnname, keytype, valuetype) \
- static int fnname (struct hashtable * htable, keytype key, valuetype value) { \
- return hashtable_insert(htable, (addr_t)key, (addr_t)value); \
- }
+ static int fnname (struct hashtable * htable, keytype key, valuetype value) { \
+ return hashtable_insert(htable, (addr_t)key, (addr_t)value); \
+ }
#define DEFINE_HASHTABLE_SEARCH(fnname, keytype, valuetype) \
- static valuetype * fnname (struct hashtable * htable, keytype key) { \
- return (valuetype *) (hashtable_search(htable, (addr_t)key)); \
- }
+ static valuetype * fnname (struct hashtable * htable, keytype key) { \
+ return (valuetype *) (hashtable_search(htable, (addr_t)key)); \
+ }
#define DEFINE_HASHTABLE_REMOVE(fnname, keytype, valuetype, free_key) \
- static valuetype * fnname (struct hashtable * htable, keytype key) { \
- return (valuetype *) (hashtable_remove(htable, (addr_t)key, free_key)); \
- }
+ static valuetype * fnname (struct hashtable * htable, keytype key) { \
+ return (valuetype *) (hashtable_remove(htable, (addr_t)key, free_key)); \
+ }
int hashtable_dec(struct hashtable * htable, addr_t key, addr_t value);
- /* ************ */
- /* ITERATOR API */
+/* ************ */
+/* ITERATOR API */
/* ************ */
#define DEFINE_HASHTABLE_ITERATOR_SEARCH(fnname, keytype) \
- int fnname (struct hashtable_itr * iter, struct hashtable * htable, keytype * key) { \
- return (hashtable_iterator_search(iter, htable, key)); \
- }
+ int fnname (struct hashtable_itr * iter, struct hashtable * htable, keytype * key) { \
+ return (hashtable_iterator_search(iter, htable, key)); \
+ }
/* This struct is only concrete here to allow the inlining of two of the
* accessor functions. */
struct hashtable_iter {
- struct hashtable * htable;
- struct hash_entry * entry;
- struct hash_entry * parent;
- uint_t index;
+ struct hashtable * htable;
+ struct hash_entry * entry;
+ struct hash_entry * parent;
+ uint_t index;
};
* LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-*/
+ */
struct v3_keyboard_event {
- unsigned char status;
- unsigned char scan_code;
+ unsigned char status;
+ unsigned char scan_code;
};
struct v3_mouse_event {
- unsigned char data[3];
+ unsigned char data[3];
};
struct v3_timer_event {
- unsigned int period_us;
+ unsigned int period_us;
};
#ifdef __V3VEE__
union v3_host_event_handler {
- int (*keyboard_handler)(struct guest_info * info, struct v3_keyboard_event * evt, void * priv_data);
- int (*mouse_handler)(struct guest_info * info, struct v3_mouse_event * evt, void * priv_data);
- int (*timer_handler)(struct guest_info * info, struct v3_timer_event * evt, void * priv_data);
+ int (*keyboard_handler)(struct guest_info * info, struct v3_keyboard_event * evt, void * priv_data);
+ int (*mouse_handler)(struct guest_info * info, struct v3_mouse_event * evt, void * priv_data);
+ int (*timer_handler)(struct guest_info * info, struct v3_timer_event * evt, void * priv_data);
};
struct v3_host_event_hook {
- union v3_host_event_handler cb;
- void * private_data;
- struct list_head link;
+ union v3_host_event_handler cb;
+ void * private_data;
+ struct list_head link;
};
struct v3_host_events {
- struct list_head keyboard_events;
- struct list_head mouse_events;
- struct list_head timer_events;
+ struct list_head keyboard_events;
+ struct list_head mouse_events;
+ struct list_head timer_events;
};
#define MAKE_1OP_8FLAGS_INST(iname) static inline void iname##8(addr_t * dst, addr_t * flags) { \
- /* Some of the flags values are not copied out in a pushf, we save them here */ \
- addr_t flags_rsvd = *flags & ~0xfffe7fff; \
+ /* Some of the flags values are not copied out in a pushf, we save them here */ \
+ addr_t flags_rsvd = *flags & ~0xfffe7fff; \
\
- asm volatile ( \
- "pushf; " \
- "push %2; " \
- "popf; " \
- #iname"b %0; " \
- "pushf; " \
- "pop %1; " \
- "popf; " \
- : "=q"(*(uint8_t *)dst),"=q"(*flags) \
- : "q"(*flags), "0"(*(uint8_t *)dst) \
- ); \
- *flags |= flags_rsvd; \
+ asm volatile ( \
+ "pushf; " \
+ "push %2; " \
+ "popf; " \
+ #iname"b %0; " \
+ "pushf; " \
+ "pop %1; " \
+ "popf; " \
+ : "=q"(*(uint8_t *)dst),"=q"(*flags) \
+ : "q"(*flags), "0"(*(uint8_t *)dst) \
+ ); \
+ *flags |= flags_rsvd; \
\
- }
+ }
#define MAKE_1OP_16FLAGS_INST(iname) static inline void iname##16(addr_t * dst, addr_t * flags) { \
- /* Some of the flags values are not copied out in a pushf, we save them here */ \
- addr_t flags_rsvd = *flags & ~0xfffe7fff; \
+ /* Some of the flags values are not copied out in a pushf, we save them here */ \
+ addr_t flags_rsvd = *flags & ~0xfffe7fff; \
\
- asm volatile ( \
- "pushf; " \
- "push %2; " \
- "popf; " \
- #iname"w %0; " \
- "pushf; " \
- "pop %1; " \
- "popf; " \
- : "=q"(*(uint16_t *)dst),"=q"(*flags) \
- : "q"(*flags), "0"(*(uint16_t *)dst) \
- ); \
- *flags |= flags_rsvd; \
+ asm volatile ( \
+ "pushf; " \
+ "push %2; " \
+ "popf; " \
+ #iname"w %0; " \
+ "pushf; " \
+ "pop %1; " \
+ "popf; " \
+ : "=q"(*(uint16_t *)dst),"=q"(*flags) \
+ : "q"(*flags), "0"(*(uint16_t *)dst) \
+ ); \
+ *flags |= flags_rsvd; \
\
- }
+ }
#define MAKE_1OP_32FLAGS_INST(iname) static inline void iname##32(addr_t * dst, addr_t * flags) { \
- /* Some of the flags values are not copied out in a pushf, we save them here */ \
- addr_t flags_rsvd = *flags & ~0xfffe7fff; \
+ /* Some of the flags values are not copied out in a pushf, we save them here */ \
+ addr_t flags_rsvd = *flags & ~0xfffe7fff; \
\
- asm volatile ( \
- "pushf; " \
- "push %2; " \
- "popf; " \
- #iname"l %0; " \
- "pushf; " \
- "pop %1; " \
- "popf; " \
- : "=q"(*(uint32_t *)dst),"=q"(*flags) \
- : "q"(*flags), "0"(*(uint32_t *)dst) \
- ); \
- *flags |= flags_rsvd; \
+ asm volatile ( \
+ "pushf; " \
+ "push %2; " \
+ "popf; " \
+ #iname"l %0; " \
+ "pushf; " \
+ "pop %1; " \
+ "popf; " \
+ : "=q"(*(uint32_t *)dst),"=q"(*flags) \
+ : "q"(*flags), "0"(*(uint32_t *)dst) \
+ ); \
+ *flags |= flags_rsvd; \
\
- }
+ }
#define MAKE_1OP_64FLAGS_INST(iname) static inline void iname##64(addr_t * dst, addr_t * flags) { \
- /* Some of the flags values are not copied out in a pushf, we save them here */ \
- addr_t flags_rsvd = *flags & ~0xfffe7fff; \
+ /* Some of the flags values are not copied out in a pushf, we save them here */ \
+ addr_t flags_rsvd = *flags & ~0xfffe7fff; \
\
- asm volatile ( \
- "pushfq; " \
- "push %2; " \
- "popfq; " \
- #iname"q %0; " \
- "pushfq; " \
- "pop %1; " \
- "popfq; " \
- : "=q"(*(uint64_t *)dst),"=q"(*flags) \
- : "q"(*flags), "0"(*(uint64_t *)dst) \
- ); \
- *flags |= flags_rsvd; \
+ asm volatile ( \
+ "pushfq; " \
+ "push %2; " \
+ "popfq; " \
+ #iname"q %0; " \
+ "pushfq; " \
+ "pop %1; " \
+ "popfq; " \
+ : "=q"(*(uint64_t *)dst),"=q"(*flags) \
+ : "q"(*flags), "0"(*(uint64_t *)dst) \
+ ); \
+ *flags |= flags_rsvd; \
\
- }
+ }
#define MAKE_1OP_8_INST(iname) static inline void iname##8(addr_t * dst) { \
- asm volatile ( \
- #iname"b %0; " \
- : "=q"(*(uint8_t *)dst) \
- : "0"(*(uint8_t *)dst) \
- ); \
- }
+ asm volatile ( \
+ #iname"b %0; " \
+ : "=q"(*(uint8_t *)dst) \
+ : "0"(*(uint8_t *)dst) \
+ ); \
+ }
#define MAKE_1OP_16_INST(iname) static inline void iname##16(addr_t * dst) { \
- asm volatile ( \
- #iname"w %0; " \
- : "=q"(*(uint16_t *)dst) \
- : "0"(*(uint16_t *)dst) \
- ); \
- }
+ asm volatile ( \
+ #iname"w %0; " \
+ : "=q"(*(uint16_t *)dst) \
+ : "0"(*(uint16_t *)dst) \
+ ); \
+ }
#define MAKE_1OP_32_INST(iname) static inline void iname##32(addr_t * dst) { \
- asm volatile ( \
- #iname"l %0; " \
- : "=q"(*(uint32_t *)dst) \
- : "0"(*(uint32_t *)dst) \
- ); \
- }
+ asm volatile ( \
+ #iname"l %0; " \
+ : "=q"(*(uint32_t *)dst) \
+ : "0"(*(uint32_t *)dst) \
+ ); \
+ }
#define MAKE_1OP_64_INST(iname) static inline void iname##64(addr_t * dst) { \
- asm volatile ( \
- #iname"q %0; " \
- : "=q"(*(uint64_t *)dst) \
- : "0"(*(uint64_t *)dst) \
- ); \
- }
+ asm volatile ( \
+ #iname"q %0; " \
+ : "=q"(*(uint64_t *)dst) \
+ : "0"(*(uint64_t *)dst) \
+ ); \
+ }
#define MAKE_2OP_64FLAGS_INST(iname) static inline void iname##64(addr_t * dst, addr_t * src, addr_t * flags) { \
- /* Some of the flags values are not copied out in a pushf, we save them here */ \
- addr_t flags_rsvd = *flags & ~0xfffe7fff; \
+ /* Some of the flags values are not copied out in a pushf, we save them here */ \
+ addr_t flags_rsvd = *flags & ~0xfffe7fff; \
\
- asm volatile ( \
- "pushfq\r\n" \
- "push %3\r\n" \
- "popfq\r\n" \
- #iname"q %2, %0\r\n" \
- "pushfq\r\n" \
- "pop %1\r\n" \
- "popfq\r\n" \
- : "=q"(*(uint64_t *)dst),"=q"(*flags) \
- : "q"(*(uint64_t *)src),"q"(*flags), "0"(*(uint64_t *)dst) \
- ); \
- *flags |= flags_rsvd; \
+ asm volatile ( \
+ "pushfq\r\n" \
+ "push %3\r\n" \
+ "popfq\r\n" \
+ #iname"q %2, %0\r\n" \
+ "pushfq\r\n" \
+ "pop %1\r\n" \
+ "popfq\r\n" \
+ : "=q"(*(uint64_t *)dst),"=q"(*flags) \
+ : "q"(*(uint64_t *)src),"q"(*flags), "0"(*(uint64_t *)dst) \
+ ); \
+ *flags |= flags_rsvd; \
\
- }
+ }
#define MAKE_2OP_32FLAGS_INST(iname) static inline void iname##32(addr_t * dst, addr_t * src, addr_t * flags) { \
- /* Some of the flags values are not copied out in a pushf, we save them here */ \
- addr_t flags_rsvd = *flags & ~0xfffe7fff; \
+ /* Some of the flags values are not copied out in a pushf, we save them here */ \
+ addr_t flags_rsvd = *flags & ~0xfffe7fff; \
\
- asm volatile ( \
- "pushf; " \
- "push %3; " \
- "popf; " \
- #iname"l %2, %0; " \
- "pushf; " \
- "pop %1; " \
- "popf; " \
- : "=q"(*(uint32_t *)dst),"=q"(*flags) \
- : "q"(*(uint32_t *)src),"q"(*flags), "0"(*(uint32_t *)dst) \
- ); \
- *flags |= flags_rsvd; \
- }
+ asm volatile ( \
+ "pushf; " \
+ "push %3; " \
+ "popf; " \
+ #iname"l %2, %0; " \
+ "pushf; " \
+ "pop %1; " \
+ "popf; " \
+ : "=q"(*(uint32_t *)dst),"=q"(*flags) \
+ : "q"(*(uint32_t *)src),"q"(*flags), "0"(*(uint32_t *)dst) \
+ ); \
+ *flags |= flags_rsvd; \
+ }
#define MAKE_2OP_16FLAGS_INST(iname) static inline void iname##16(addr_t * dst, addr_t * src, addr_t * flags) { \
- /* Some of the flags values are not copied out in a pushf, we save them here */ \
- addr_t flags_rsvd = *flags & ~0xfffe7fff; \
+ /* Some of the flags values are not copied out in a pushf, we save them here */ \
+ addr_t flags_rsvd = *flags & ~0xfffe7fff; \
\
- asm volatile ( \
- "pushf; " \
- "push %3; " \
- "popf; " \
- #iname"w %2, %0; " \
- "pushf; " \
- "pop %1; " \
- "popf; " \
- : "=q"(*(uint16_t *)dst),"=q"(*flags) \
- : "q"(*(uint16_t *)src),"q"(*flags), "0"(*(uint16_t *)dst) \
- ); \
- *flags |= flags_rsvd; \
- }
+ asm volatile ( \
+ "pushf; " \
+ "push %3; " \
+ "popf; " \
+ #iname"w %2, %0; " \
+ "pushf; " \
+ "pop %1; " \
+ "popf; " \
+ : "=q"(*(uint16_t *)dst),"=q"(*flags) \
+ : "q"(*(uint16_t *)src),"q"(*flags), "0"(*(uint16_t *)dst) \
+ ); \
+ *flags |= flags_rsvd; \
+ }
#define MAKE_2OP_8FLAGS_INST(iname) static inline void iname##8(addr_t * dst, addr_t * src, addr_t * flags) { \
- /* Some of the flags values are not copied out in a pushf, we save them here */ \
- addr_t flags_rsvd = *flags & ~0xfffe7fff; \
+ /* Some of the flags values are not copied out in a pushf, we save them here */ \
+ addr_t flags_rsvd = *flags & ~0xfffe7fff; \
\
- asm volatile ( \
- "pushf; " \
- "push %3; " \
- "popf; " \
- #iname"b %2, %0; " \
- "pushf; " \
- "pop %1; " \
- "popf; " \
- : "=q"(*(uint8_t *)dst),"=q"(*flags) \
- : "q"(*(uint8_t *)src),"q"(*flags), "0"(*(uint8_t *)dst) \
- ); \
- *flags |= flags_rsvd; \
- }
+ asm volatile ( \
+ "pushf; " \
+ "push %3; " \
+ "popf; " \
+ #iname"b %2, %0; " \
+ "pushf; " \
+ "pop %1; " \
+ "popf; " \
+ : "=q"(*(uint8_t *)dst),"=q"(*flags) \
+ : "q"(*(uint8_t *)src),"q"(*flags), "0"(*(uint8_t *)dst) \
+ ); \
+ *flags |= flags_rsvd; \
+ }
#define MAKE_2OP_64STR_INST(iname) static inline void iname##64(addr_t * dst, \
addr_t * src, \
addr_t * ecx, addr_t * flags) { \
- /* Some of the flags values are not copied out in a pushf, we save them here */ \
- addr_t flags_rsvd = *flags & ~0xfffe7fff; \
+ /* Some of the flags values are not copied out in a pushf, we save them here */ \
+ addr_t flags_rsvd = *flags & ~0xfffe7fff; \
\
- asm volatile ( \
- "pushfq; " \
- "pushq %4; " \
- "popfq; " \
- "rep; " \
- #iname"q; " \
- "pushfq; " \
- "popq %0; " \
- "popfq; " \
- : "=q"(*flags) \
- : "D"(*dst),"S"(*src),"c"(*ecx),"q"(*flags) \
- ); \
- *flags |= flags_rsvd; \
- }
+ asm volatile ( \
+ "pushfq; " \
+ "pushq %4; " \
+ "popfq; " \
+ "rep; " \
+ #iname"q; " \
+ "pushfq; " \
+ "popq %0; " \
+ "popfq; " \
+ : "=q"(*flags) \
+ : "D"(*dst),"S"(*src),"c"(*ecx),"q"(*flags) \
+ ); \
+ *flags |= flags_rsvd; \
+ }
#define MAKE_2OP_32STR_INST(iname) static inline void iname##32(addr_t * dst, \
addr_t * src, \
addr_t * ecx, addr_t * flags) { \
- /* Some of the flags values are not copied out in a pushf, we save them here */ \
- addr_t flags_rsvd = *flags & ~0xfffe7fff; \
+ /* Some of the flags values are not copied out in a pushf, we save them here */ \
+ addr_t flags_rsvd = *flags & ~0xfffe7fff; \
\
- asm volatile ( \
- "pushf; " \
- "push %4; " \
- "popf; " \
- "rep; " \
- #iname"l; " \
- "pushf; " \
- "pop %0; " \
- "popf; " \
- : "=q"(*flags) \
- : "D"(*dst),"S"(*src),"c"(*ecx),"q"(*flags) \
- ); \
- *flags |= flags_rsvd; \
- }
+ asm volatile ( \
+ "pushf; " \
+ "push %4; " \
+ "popf; " \
+ "rep; " \
+ #iname"l; " \
+ "pushf; " \
+ "pop %0; " \
+ "popf; " \
+ : "=q"(*flags) \
+ : "D"(*dst),"S"(*src),"c"(*ecx),"q"(*flags) \
+ ); \
+ *flags |= flags_rsvd; \
+ }
#define MAKE_2OP_16STR_INST(iname) static inline void iname##16(addr_t * dst, \
addr_t * src, \
addr_t * ecx, addr_t * flags) { \
- /* Some of the flags values are not copied out in a pushf, we save them here */ \
- addr_t flags_rsvd = *flags & ~0xfffe7fff; \
+ /* Some of the flags values are not copied out in a pushf, we save them here */ \
+ addr_t flags_rsvd = *flags & ~0xfffe7fff; \
\
- asm volatile ( \
- "pushf; " \
- "push %4; " \
- "popf; " \
- "rep; " \
- #iname"w; " \
- "pushf; " \
- "pop %0; " \
- "popf; " \
- : "=q"(*flags) \
- : "D"(*dst),"S"(*src),"c"(*ecx),"q"(*flags) \
- ); \
- *flags |= flags_rsvd; \
- }
+ asm volatile ( \
+ "pushf; " \
+ "push %4; " \
+ "popf; " \
+ "rep; " \
+ #iname"w; " \
+ "pushf; " \
+ "pop %0; " \
+ "popf; " \
+ : "=q"(*flags) \
+ : "D"(*dst),"S"(*src),"c"(*ecx),"q"(*flags) \
+ ); \
+ *flags |= flags_rsvd; \
+ }
#define MAKE_2OP_8STR_INST(iname) static inline void iname##8(addr_t * dst, \
addr_t * src, \
addr_t * ecx, addr_t * flags) { \
- /* Some of the flags values are not copied out in a pushf, we save them here */ \
- addr_t flags_rsvd = *flags & ~0xfffe7fff; \
+ /* Some of the flags values are not copied out in a pushf, we save them here */ \
+ addr_t flags_rsvd = *flags & ~0xfffe7fff; \
\
- asm volatile ( \
- "pushf; " \
- "push %4; " \
- "popf; " \
- "rep; " \
- #iname"b; " \
- "pushf; " \
- "pop %0; " \
- "popf; " \
- : "=q"(*flags) \
- : "D"(*dst),"S"(*src),"c"(*ecx),"q"(*flags) \
- ); \
- *flags |= flags_rsvd; \
- }
+ asm volatile ( \
+ "pushf; " \
+ "push %4; " \
+ "popf; " \
+ "rep; " \
+ #iname"b; " \
+ "pushf; " \
+ "pop %0; " \
+ "popf; " \
+ : "=q"(*flags) \
+ : "D"(*dst),"S"(*src),"c"(*ecx),"q"(*flags) \
+ ); \
+ *flags |= flags_rsvd; \
+ }
#define MAKE_1OP_64STR_INST(iname) static inline void iname##64(addr_t * dst, \
addr_t * src, \
addr_t * ecx, addr_t * flags) { \
- /* Some of the flags values are not copied out in a pushf, we save them here */ \
- addr_t flags_rsvd = *flags & ~0xfffe7fff; \
+ /* Some of the flags values are not copied out in a pushf, we save them here */ \
+ addr_t flags_rsvd = *flags & ~0xfffe7fff; \
\
- asm volatile ( \
- "pushfq; " \
- "pushq %4; " \
- "popfq; " \
- "rep; " \
- #iname"q; " \
- "pushfq; " \
- "popq %0; " \
- "popfq; " \
- : "=q"(*flags) \
- : "D"(*dst),"a"(*src),"c"(*ecx),"q"(*flags) \
- ); \
+ asm volatile ( \
+ "pushfq; " \
+ "pushq %4; " \
+ "popfq; " \
+ "rep; " \
+ #iname"q; " \
+ "pushfq; " \
+ "popq %0; " \
+ "popfq; " \
+ : "=q"(*flags) \
+ : "D"(*dst),"a"(*src),"c"(*ecx),"q"(*flags) \
+ ); \
\
- *flags |= flags_rsvd; \
- }
+ *flags |= flags_rsvd; \
+ }
#define MAKE_1OP_32STR_INST(iname) static inline void iname##32(addr_t * dst, \
addr_t * src, \
addr_t * ecx, addr_t * flags) { \
- /* Some of the flags values are not copied out in a pushf, we save them here */ \
- addr_t flags_rsvd = *flags & ~0xfffe7fff; \
+ /* Some of the flags values are not copied out in a pushf, we save them here */ \
+ addr_t flags_rsvd = *flags & ~0xfffe7fff; \
\
- asm volatile ( \
- "pushf; " \
- "push %4; " \
- "popf; " \
- "rep; " \
- #iname"l; " \
- "pushf; " \
- "pop %0; " \
- "popf; " \
- : "=q"(*flags) \
- : "D"(*(uint32_t *)dst),"a"(*(uint32_t *)src),"c"(*(uint32_t *)ecx),"q"(*flags) \
- ); \
- *flags |= flags_rsvd; \
- }
+ asm volatile ( \
+ "pushf; " \
+ "push %4; " \
+ "popf; " \
+ "rep; " \
+ #iname"l; " \
+ "pushf; " \
+ "pop %0; " \
+ "popf; " \
+ : "=q"(*flags) \
+ : "D"(*(uint32_t *)dst),"a"(*(uint32_t *)src),"c"(*(uint32_t *)ecx),"q"(*flags) \
+ ); \
+ *flags |= flags_rsvd; \
+ }
#define MAKE_1OP_16STR_INST(iname) static inline void iname##16(addr_t * dst, \
addr_t * src, \
addr_t * ecx, addr_t * flags) { \
- /* Some of the flags values are not copied out in a pushf, we save them here */ \
- addr_t flags_rsvd = *flags & ~0xfffe7fff; \
+ /* Some of the flags values are not copied out in a pushf, we save them here */ \
+ addr_t flags_rsvd = *flags & ~0xfffe7fff; \
\
- asm volatile ( \
- "pushf; " \
- "push %4; " \
- "popf; " \
- "rep; " \
- #iname"w; " \
- "pushf; " \
- "pop %0; " \
- "popf; " \
- : "=q"(*flags) \
- : "D"(*dst),"a"(*src),"c"(*ecx),"q"(*flags) \
- ); \
- *flags |= flags_rsvd; \
- }
+ asm volatile ( \
+ "pushf; " \
+ "push %4; " \
+ "popf; " \
+ "rep; " \
+ #iname"w; " \
+ "pushf; " \
+ "pop %0; " \
+ "popf; " \
+ : "=q"(*flags) \
+ : "D"(*dst),"a"(*src),"c"(*ecx),"q"(*flags) \
+ ); \
+ *flags |= flags_rsvd; \
+ }
#define MAKE_1OP_8STR_INST(iname) static inline void iname##8(addr_t * dst, \
addr_t * src, \
addr_t * ecx, addr_t * flags) { \
- /* Some of the flags values are not copied out in a pushf, we save them here */ \
- addr_t flags_rsvd = *flags & ~0xfffe7fff; \
+ /* Some of the flags values are not copied out in a pushf, we save them here */ \
+ addr_t flags_rsvd = *flags & ~0xfffe7fff; \
\
- asm volatile ( \
- "pushf; " \
- "push %4; " \
- "popf; " \
- "rep; " \
- #iname"b; " \
- "pushf; " \
- "pop %0; " \
- "popf; " \
- : "=q"(*flags) \
- : "D"(*dst),"a"(*src),"c"(*ecx),"q"(*flags) \
- ); \
- *flags |= flags_rsvd; \
- }
+ asm volatile ( \
+ "pushf; " \
+ "push %4; " \
+ "popf; " \
+ "rep; " \
+ #iname"b; " \
+ "pushf; " \
+ "pop %0; " \
+ "popf; " \
+ : "=q"(*flags) \
+ : "D"(*dst),"a"(*src),"c"(*ecx),"q"(*flags) \
+ ); \
+ *flags |= flags_rsvd; \
+ }
#define MAKE_2OP_64_INST(iname) static inline void iname##64(addr_t * dst, addr_t * src) { \
- asm volatile ( \
- #iname"q %1, %0; " \
- : "=q"(*(uint64_t *)dst) \
- : "q"(*(uint64_t *)src), "0"(*(uint64_t *)dst) \
- ); \
- }
+ asm volatile ( \
+ #iname"q %1, %0; " \
+ : "=q"(*(uint64_t *)dst) \
+ : "q"(*(uint64_t *)src), "0"(*(uint64_t *)dst) \
+ ); \
+ }
#define MAKE_2OP_32_INST(iname) static inline void iname##32(addr_t * dst, addr_t * src) { \
- asm volatile ( \
- #iname"l %1, %0; " \
- : "=q"(*(uint32_t *)dst) \
- : "q"(*(uint32_t *)src), "0"(*(uint32_t *)dst) \
- ); \
- }
+ asm volatile ( \
+ #iname"l %1, %0; " \
+ : "=q"(*(uint32_t *)dst) \
+ : "q"(*(uint32_t *)src), "0"(*(uint32_t *)dst) \
+ ); \
+ }
#define MAKE_2OP_16_INST(iname) static inline void iname##16(addr_t * dst, addr_t * src) { \
- asm volatile ( \
- #iname"w %1, %0; " \
- : "=q"(*(uint16_t *)dst) \
- : "q"(*(uint16_t *)src), "0"(*(uint16_t *)dst) \
- ); \
- }
+ asm volatile ( \
+ #iname"w %1, %0; " \
+ : "=q"(*(uint16_t *)dst) \
+ : "q"(*(uint16_t *)src), "0"(*(uint16_t *)dst) \
+ ); \
+ }
#define MAKE_2OP_8_INST(iname) static inline void iname##8(addr_t * dst, addr_t * src) { \
- asm volatile ( \
- #iname"b %1, %0; " \
- : "=q"(*(uint8_t *)dst) \
- : "q"(*(uint8_t *)src), "0"(*(uint8_t *)dst) \
- ); \
- }
+ asm volatile ( \
+ #iname"b %1, %0; " \
+ : "=q"(*(uint8_t *)dst) \
+ : "q"(*(uint8_t *)src), "0"(*(uint8_t *)dst) \
+ ); \
+ }
#define MAKE_2OP_8EXT_INST(iname) static inline void iname##8(addr_t * dst, addr_t * src, uint_t dst_len) { \
- if (dst_len == 2) { \
- asm volatile ( \
- #iname" %1, %0; " \
- : "=q"(*(uint16_t *)dst) \
- : "q"(*(uint8_t *)src), "0"(*(uint16_t *)dst) \
- ); \
- } else if (dst_len == 4) { \
- asm volatile ( \
- #iname" %1, %0; " \
- : "=q"(*(uint32_t *)dst) \
- : "q"(*(uint8_t *)src), "0"(*(uint32_t *)dst) \
- ); \
- } else if (dst_len == 8) { \
- asm volatile ( \
- #iname" %1, %0; " \
- : "=q"(*(uint64_t *)dst) \
- : "q"(*(uint8_t *)src), "0"(*(uint64_t *)dst) \
- ); \
- } \
- }
+ if (dst_len == 2) { \
+ asm volatile ( \
+ #iname" %1, %0; " \
+ : "=q"(*(uint16_t *)dst) \
+ : "q"(*(uint8_t *)src), "0"(*(uint16_t *)dst) \
+ ); \
+ } else if (dst_len == 4) { \
+ asm volatile ( \
+ #iname" %1, %0; " \
+ : "=q"(*(uint32_t *)dst) \
+ : "q"(*(uint8_t *)src), "0"(*(uint32_t *)dst) \
+ ); \
+ } else if (dst_len == 8) { \
+ asm volatile ( \
+ #iname" %1, %0; " \
+ : "=q"(*(uint64_t *)dst) \
+ : "q"(*(uint8_t *)src), "0"(*(uint64_t *)dst) \
+ ); \
+ } \
+ }
#define MAKE_2OP_16EXT_INST(iname) static inline void iname##16(addr_t * dst, addr_t * src, uint_t dst_len) { \
- if (dst_len == 4) { \
- asm volatile ( \
- #iname" %1, %0; " \
- : "=q"(*(uint32_t *)dst) \
- : "q"(*(uint16_t *)src), "0"(*(uint32_t *)dst) \
- ); \
- } else if (dst_len == 8) { \
- asm volatile ( \
- #iname" %1, %0; " \
- : "=q"(*(uint64_t *)dst) \
- : "q"(*(uint16_t *)src), "0"(*(uint64_t *)dst) \
- ); \
- } \
- }
+ if (dst_len == 4) { \
+ asm volatile ( \
+ #iname" %1, %0; " \
+ : "=q"(*(uint32_t *)dst) \
+ : "q"(*(uint16_t *)src), "0"(*(uint32_t *)dst) \
+ ); \
+ } else if (dst_len == 8) { \
+ asm volatile ( \
+ #iname" %1, %0; " \
+ : "=q"(*(uint64_t *)dst) \
+ : "q"(*(uint16_t *)src), "0"(*(uint64_t *)dst) \
+ ); \
+ } \
+ }
#define MAKE_2OUT_64_INST(iname) static inline void iname##64(addr_t * dst, addr_t * src) { \
- asm volatile ( \
- #iname"q %1, %0; " \
- : "=q"(*(uint64_t *)dst), "=q"(*(uint64_t *)src) \
- : "0"(*(uint64_t *)dst), "1"(*(uint64_t *)src) \
- ); \
- }
+ asm volatile ( \
+ #iname"q %1, %0; " \
+ : "=q"(*(uint64_t *)dst), "=q"(*(uint64_t *)src) \
+ : "0"(*(uint64_t *)dst), "1"(*(uint64_t *)src) \
+ ); \
+ }
#define MAKE_2OUT_32_INST(iname) static inline void iname##32(addr_t * dst, addr_t * src) { \
- asm volatile ( \
- #iname"l %1, %0; " \
- : "=q"(*(uint32_t *)dst), "=q"(*(uint32_t *)src) \
- : "0"(*(uint32_t *)dst), "1"(*(uint32_t *)src) \
- ); \
- }
+ asm volatile ( \
+ #iname"l %1, %0; " \
+ : "=q"(*(uint32_t *)dst), "=q"(*(uint32_t *)src) \
+ : "0"(*(uint32_t *)dst), "1"(*(uint32_t *)src) \
+ ); \
+ }
#define MAKE_2OUT_16_INST(iname) static inline void iname##16(addr_t * dst, addr_t * src) { \
- asm volatile ( \
- #iname"w %1, %0; " \
- : "=q"(*(uint16_t *)dst), "=q"(*(uint16_t *)src) \
- : "0"(*(uint16_t *)dst), "1"(*(uint16_t *)src) \
- ); \
- }
+ asm volatile ( \
+ #iname"w %1, %0; " \
+ : "=q"(*(uint16_t *)dst), "=q"(*(uint16_t *)src) \
+ : "0"(*(uint16_t *)dst), "1"(*(uint16_t *)src) \
+ ); \
+ }
#define MAKE_2OUT_8_INST(iname) static inline void iname##8(addr_t * dst, addr_t * src) { \
- asm volatile ( \
- #iname"b %1, %0; " \
- : "=q"(*(uint8_t *)dst), "=q"(*(uint8_t *)src) \
- : "0"(*(uint8_t *)dst), "1"(*(uint8_t *)src) \
- ); \
- }
+ asm volatile ( \
+ #iname"b %1, %0; " \
+ : "=q"(*(uint8_t *)dst), "=q"(*(uint8_t *)src) \
+ : "0"(*(uint8_t *)dst), "1"(*(uint8_t *)src) \
+ ); \
+ }
struct v3_irq_hook {
- int (*handler)(struct guest_info * info, struct v3_interrupt * intr, void * priv_data);
- void * priv_data;
+ int (*handler)(struct guest_info * info, struct v3_interrupt * intr, void * priv_data);
+ void * priv_data;
};
struct v3_intr_state {
- /* We need to rework the exception state, to handle stacking */
- uint_t excp_pending;
- uint_t excp_num;
- uint_t excp_error_code_valid : 1;
- uint_t excp_error_code;
+ /* We need to rework the exception state, to handle stacking */
+ uint_t excp_pending;
+ uint_t excp_num;
+ uint_t excp_error_code_valid : 1;
+ uint_t excp_error_code;
- struct list_head controller_list;
+ struct list_head controller_list;
- /* some way to get the [A]PIC intr */
- struct v3_irq_hook * hooks[256];
+ /* some way to get the [A]PIC intr */
+ struct v3_irq_hook * hooks[256];
};
struct intr_ctrl_ops {
- int (*intr_pending)(void * private_data);
- int (*get_intr_number)(void * private_data);
- int (*raise_intr)(void * private_data, int irq);
- int (*lower_intr)(void * private_data, int irq);
- int (*begin_irq)(void * private_data, int irq);
+ int (*intr_pending)(void * private_data);
+ int (*get_intr_number)(void * private_data);
+ int (*raise_intr)(void * private_data, int irq);
+ int (*lower_intr)(void * private_data, int irq);
+ int (*begin_irq)(void * private_data, int irq);
};
int v3_injecting_intr(struct guest_info * info, uint_t intr_num, intr_type_t type);
/*
-int start_irq(struct vm_intr * intr);
-int end_irq(struct vm_intr * intr, int irq);
+ int start_irq(struct vm_intr * intr);
+ int end_irq(struct vm_intr * intr, int irq);
*/
struct v3_io_hook {
- ushort_t port;
+ ushort_t port;
- // Reads data into the IO port (IN, INS)
- int (*read)(ushort_t port, void * dst, uint_t length, void * priv_data);
+ // Reads data into the IO port (IN, INS)
+ int (*read)(ushort_t port, void * dst, uint_t length, void * priv_data);
- // Writes data from the IO port (OUT, OUTS)
- int (*write)(ushort_t port, void * src, uint_t length, void * priv_data);
+ // Writes data from the IO port (OUT, OUTS)
+ int (*write)(ushort_t port, void * src, uint_t length, void * priv_data);
- void * priv_data;
+ void * priv_data;
- struct rb_node tree_node;
+ struct rb_node tree_node;
};
#ifdef __V3_32BIT__
void __inline__ v3_cpuid(uint_t target, addr_t * eax, addr_t * ebx, addr_t * ecx, addr_t * edx) {
- __asm__ __volatile__ (
- "pushl %%ebx\n\t"
- "cpuid\n\t"
- "movl %%ebx, %%esi\n\t"
- "popl %%ebx\n\t"
- : "=a" (*eax), "=S" (*ebx), "=c" (*ecx), "=d" (*edx)
- : "a" (target)
- );
- return;
+ __asm__ __volatile__ (
+ "pushl %%ebx\n\t"
+ "cpuid\n\t"
+ "movl %%ebx, %%esi\n\t"
+ "popl %%ebx\n\t"
+ : "=a" (*eax), "=S" (*ebx), "=c" (*ecx), "=d" (*edx)
+ : "a" (target)
+ );
+ return;
}
#elif __V3_64BIT__
void __inline__ v3_cpuid(uint_t target, addr_t * eax, addr_t * ebx, addr_t * ecx, addr_t * edx) {
- __asm__ __volatile__ (
- "pushq %%rbx\n\t"
- "cpuid\n\t"
- "movq %%rbx, %%rsi\n\t"
- "popq %%rbx\n\t"
- : "=a" (*eax), "=S" (*ebx), "=c" (*ecx), "=d" (*edx)
- : "a" (target)
- );
- return;
+ __asm__ __volatile__ (
+ "pushq %%rbx\n\t"
+ "cpuid\n\t"
+ "movq %%rbx, %%rsi\n\t"
+ "popq %%rbx\n\t"
+ : "=a" (*eax), "=S" (*ebx), "=c" (*ecx), "=d" (*edx)
+ : "a" (target)
+ );
+ return;
}
#endif
void __inline__ v3_set_msr(uint_t msr, uint_t high_byte, uint_t low_byte) {
- __asm__ __volatile__ (
- "wrmsr"
- :
- : "c" (msr), "d" (high_byte), "a" (low_byte)
- );
+ __asm__ __volatile__ (
+ "wrmsr"
+ :
+ : "c" (msr), "d" (high_byte), "a" (low_byte)
+ );
}
void __inline__ v3_get_msr(uint_t msr, uint_t * high_byte, uint_t * low_byte) {
- __asm__ __volatile__ (
- "rdmsr"
- : "=d" (*high_byte), "=a" (*low_byte)
- : "c" (msr)
- );
+ __asm__ __volatile__ (
+ "rdmsr"
+ : "=d" (*high_byte), "=a" (*low_byte)
+ : "c" (msr)
+ );
}
void __inline__ v3_enable_ints() {
- __asm__ __volatile__ ("sti");
+ __asm__ __volatile__ ("sti");
}
void __inline__ v3_disable_ints() {
- __asm__ __volatile__ ("cli");
+ __asm__ __volatile__ ("cli");
}
// These are the types of physical memory address regions
// from the perspective of the HOST
typedef enum shdw_region_type {
- SHDW_REGION_INVALID, // This region is INVALID (this is a return type to denote errors)
- SHDW_REGION_WRITE_HOOK, // This region is mapped as read-only (page faults on write)
- SHDW_REGION_FULL_HOOK, // This region is mapped as not present (always generate page faults)
- SHDW_REGION_ALLOCATED, // Region is a section of host memory
+ SHDW_REGION_INVALID, // This region is INVALID (this is a return type to denote errors)
+ SHDW_REGION_WRITE_HOOK, // This region is mapped as read-only (page faults on write)
+ SHDW_REGION_FULL_HOOK, // This region is mapped as not present (always generate page faults)
+ SHDW_REGION_ALLOCATED, // Region is a section of host memory
} v3_shdw_region_type_t;
typedef struct v3_shdw_map {
- addr_t hook_hva;
+ addr_t hook_hva;
- struct rb_root shdw_regions;
+ struct rb_root shdw_regions;
} v3_shdw_map_t;
struct v3_shadow_region {
- addr_t guest_start;
- addr_t guest_end;
+ addr_t guest_start;
+ addr_t guest_end;
- v3_shdw_region_type_t host_type;
+ v3_shdw_region_type_t host_type;
- addr_t host_addr; // This either points to a host address mapping
+ addr_t host_addr; // This either points to a host address mapping
- // Called when data is read from a memory page
- int (*read_hook)(addr_t guest_addr, void * dst, uint_t length, void * priv_data);
- // Called when data is written to a memory page
- int (*write_hook)(addr_t guest_addr, void * src, uint_t length, void * priv_data);
+ // Called when data is read from a memory page
+ int (*read_hook)(addr_t guest_addr, void * dst, uint_t length, void * priv_data);
+ // Called when data is written to a memory page
+ int (*write_hook)(addr_t guest_addr, void * src, uint_t length, void * priv_data);
- void * priv_data;
+ void * priv_data;
- struct rb_node tree_node;
+ struct rb_node tree_node;
};
struct v3_msr {
- union {
- ullong_t value;
+ union {
+ ullong_t value;
- struct {
- uint_t lo;
- uint_t hi;
+ struct {
+ uint_t lo;
+ uint_t hi;
+ } __attribute__((packed));
} __attribute__((packed));
- } __attribute__((packed));
} __attribute__((packed));
typedef struct v3_msr v3_msr_t;
struct v3_msr_hook {
- uint_t msr;
+ uint_t msr;
- int (*read)(uint_t msr, struct v3_msr * dst, void * priv_data);
- int (*write)(uint_t msr, struct v3_msr src, void * priv_data);
+ int (*read)(uint_t msr, struct v3_msr * dst, void * priv_data);
+ int (*write)(uint_t msr, struct v3_msr src, void * priv_data);
- void * priv_data;
+ void * priv_data;
- struct list_head link;
+ struct list_head link;
};
struct v3_msr_hook;
struct v3_msr_map {
- uint_t num_hooks;
- struct list_head hook_list;
+ uint_t num_hooks;
+ struct list_head hook_list;
};
guest-visible paging state
- This is the state that the guest thinks the machine is using
- It consists of
- - guest physical memory
- The physical memory addresses the guest is allowed to use
- (see shadow page maps, below)
- - guest page tables
- (we care about when the current one changes)
- - guest paging registers (these are never written to hardware)
- CR0
- CR3
+This is the state that the guest thinks the machine is using
+It consists of
+- guest physical memory
+The physical memory addresses the guest is allowed to use
+(see shadow page maps, below)
+- guest page tables
+(we care about when the current one changes)
+- guest paging registers (these are never written to hardware)
+CR0
+CR3
shadow paging state
- This the state that the machine will actually use when the guest
- is running. It consists of:
- - current shadow page table
- This is the page table actually useed when the guest is running.
- It is changed/regenerated when the guest page table changes
- It mostly reflects the guest page table, except that it restricts
- physical addresses to those the VMM allocates to the guest.
- - shadow page maps
- This is a mapping from guest physical memory addresses to
- the current location of the guest physical memory content.
- It maps from regions of physical memory addresses to regions
- located in physical memory or elsewhere.
- (8192,16384) -> MEM(8912,...)
- (0,8191) -> DISK(65536,..)
- - guest paging registers (these are written to guest state)
- CR0
- CR3
+This the state that the machine will actually use when the guest
+is running. It consists of:
+- current shadow page table
+This is the page table actually useed when the guest is running.
+It is changed/regenerated when the guest page table changes
+It mostly reflects the guest page table, except that it restricts
+physical addresses to those the VMM allocates to the guest.
+- shadow page maps
+This is a mapping from guest physical memory addresses to
+the current location of the guest physical memory content.
+It maps from regions of physical memory addresses to regions
+located in physical memory or elsewhere.
+(8192,16384) -> MEM(8912,...)
+(0,8191) -> DISK(65536,..)
+- guest paging registers (these are written to guest state)
+CR0
+CR3
host paging state
- This is the state we expect to be operative when the VMM is running.
- Typically, this is set up by the host os into which we have embedded
- the VMM, but we include the description here for clarity.
- - current page table
- This is the page table we use when we are executing in
- the VMM (or the host os)
- - paging regisers
- CR0
- CR3
+This is the state we expect to be operative when the VMM is running.
+Typically, this is set up by the host os into which we have embedded
+the VMM, but we include the description here for clarity.
+- current page table
+This is the page table we use when we are executing in
+the VMM (or the host os)
+- paging regisers
+CR0
+CR3
The reason why the shadow paging state and the host paging state are
typedef enum {PT_ENTRY_NOT_PRESENT, PT_ENTRY_LARGE_PAGE, PT_ENTRY_PAGE} pt_entry_type_t;
+
typedef enum {PT_ACCESS_OK, PT_ACCESS_NOT_PRESENT, PT_ACCESS_WRITE_ERROR, PT_ACCESS_USER_ERROR} pt_access_status_t;
typedef struct gen_pt {
- uint_t present : 1;
- uint_t writable : 1;
- uint_t user_page : 1;
+ uint_t present : 1;
+ uint_t writable : 1;
+ uint_t user_page : 1;
} __attribute__((packed)) gen_pt_t;
typedef struct pde32 {
- uint_t present : 1;
- uint_t writable : 1;
- uint_t user_page : 1;
- uint_t write_through : 1;
- uint_t cache_disable : 1;
- uint_t accessed : 1;
- uint_t reserved : 1;
- uint_t large_page : 1;
- uint_t global_page : 1;
- uint_t vmm_info : 3;
- uint_t pt_base_addr : 20;
+ uint_t present : 1;
+ uint_t writable : 1;
+ uint_t user_page : 1;
+ uint_t write_through : 1;
+ uint_t cache_disable : 1;
+ uint_t accessed : 1;
+ uint_t reserved : 1;
+ uint_t large_page : 1;
+ uint_t global_page : 1;
+ uint_t vmm_info : 3;
+ uint_t pt_base_addr : 20;
} __attribute__((packed)) pde32_t;
typedef struct pde32_4MB {
- uint_t present : 1;
- uint_t writable : 1;
- uint_t user_page : 1;
- uint_t write_through : 1;
- uint_t cache_disable : 1;
- uint_t accessed : 1;
- uint_t dirty : 1;
- uint_t large_page : 1;
- uint_t global_page : 1;
- uint_t vmm_info : 3;
- uint_t pat : 1;
- uint_t rsvd : 9;
- uint_t page_base_addr : 10;
+ uint_t present : 1;
+ uint_t writable : 1;
+ uint_t user_page : 1;
+ uint_t write_through : 1;
+ uint_t cache_disable : 1;
+ uint_t accessed : 1;
+ uint_t dirty : 1;
+ uint_t large_page : 1;
+ uint_t global_page : 1;
+ uint_t vmm_info : 3;
+ uint_t pat : 1;
+ uint_t rsvd : 9;
+ uint_t page_base_addr : 10;
} __attribute__((packed)) pde32_4MB_t;
typedef struct pte32 {
- uint_t present : 1;
- uint_t writable : 1;
- uint_t user_page : 1;
- uint_t write_through : 1;
- uint_t cache_disable : 1;
- uint_t accessed : 1;
- uint_t dirty : 1;
- uint_t pte_attr : 1;
- uint_t global_page : 1;
- uint_t vmm_info : 3;
- uint_t page_base_addr : 20;
+ uint_t present : 1;
+ uint_t writable : 1;
+ uint_t user_page : 1;
+ uint_t write_through : 1;
+ uint_t cache_disable : 1;
+ uint_t accessed : 1;
+ uint_t dirty : 1;
+ uint_t pte_attr : 1;
+ uint_t global_page : 1;
+ uint_t vmm_info : 3;
+ uint_t page_base_addr : 20;
} __attribute__((packed)) pte32_t;
/* ***** */
/* 32 bit PAE PAGE STRUCTURES */
typedef struct pdpe32pae {
- uint_t present : 1;
- uint_t rsvd : 2; // MBZ
- uint_t write_through : 1;
- uint_t cache_disable : 1;
- uint_t accessed : 1;
- uint_t avail : 1;
- uint_t rsvd2 : 2; // MBZ
- uint_t vmm_info : 3;
- uint_t pd_base_addr : 24;
- uint_t rsvd3 : 28; // MBZ
+ uint_t present : 1;
+ uint_t rsvd : 2; // MBZ
+ uint_t write_through : 1;
+ uint_t cache_disable : 1;
+ uint_t accessed : 1;
+ uint_t avail : 1;
+ uint_t rsvd2 : 2; // MBZ
+ uint_t vmm_info : 3;
+ uint_t pd_base_addr : 24;
+ uint_t rsvd3 : 28; // MBZ
} __attribute__((packed)) pdpe32pae_t;
typedef struct pde32pae {
- uint_t present : 1;
- uint_t writable : 1;
- uint_t user_page : 1;
- uint_t write_through : 1;
- uint_t cache_disable : 1;
- uint_t accessed : 1;
- uint_t avail : 1;
- uint_t large_page : 1;
- uint_t global_page : 1;
- uint_t vmm_info : 3;
- uint_t pt_base_addr : 24;
- uint_t rsvd : 28;
+ uint_t present : 1;
+ uint_t writable : 1;
+ uint_t user_page : 1;
+ uint_t write_through : 1;
+ uint_t cache_disable : 1;
+ uint_t accessed : 1;
+ uint_t avail : 1;
+ uint_t large_page : 1;
+ uint_t global_page : 1;
+ uint_t vmm_info : 3;
+ uint_t pt_base_addr : 24;
+ uint_t rsvd : 28;
} __attribute__((packed)) pde32pae_t;
typedef struct pde32pae_2MB {
- uint_t present : 1;
- uint_t writable : 1;
- uint_t user_page : 1;
- uint_t write_through : 1;
- uint_t cache_disable : 1;
- uint_t accessed : 1;
- uint_t dirty : 1;
- uint_t one : 1;
- uint_t global_page : 1;
- uint_t vmm_info : 3;
- uint_t pat : 1;
- uint_t rsvd : 8;
- uint_t page_base_addr : 15;
- uint_t rsvd2 : 28;
+ uint_t present : 1;
+ uint_t writable : 1;
+ uint_t user_page : 1;
+ uint_t write_through : 1;
+ uint_t cache_disable : 1;
+ uint_t accessed : 1;
+ uint_t dirty : 1;
+ uint_t one : 1;
+ uint_t global_page : 1;
+ uint_t vmm_info : 3;
+ uint_t pat : 1;
+ uint_t rsvd : 8;
+ uint_t page_base_addr : 15;
+ uint_t rsvd2 : 28;
} __attribute__((packed)) pde32pae_2MB_t;
typedef struct pte32pae {
- uint_t present : 1;
- uint_t writable : 1;
- uint_t user_page : 1;
- uint_t write_through : 1;
- uint_t cache_disable : 1;
- uint_t accessed : 1;
- uint_t dirty : 1;
- uint_t pte_attr : 1;
- uint_t global_page : 1;
- uint_t vmm_info : 3;
- uint_t page_base_addr : 24;
- uint_t rsvd : 28;
+ uint_t present : 1;
+ uint_t writable : 1;
+ uint_t user_page : 1;
+ uint_t write_through : 1;
+ uint_t cache_disable : 1;
+ uint_t accessed : 1;
+ uint_t dirty : 1;
+ uint_t pte_attr : 1;
+ uint_t global_page : 1;
+ uint_t vmm_info : 3;
+ uint_t page_base_addr : 24;
+ uint_t rsvd : 28;
} __attribute__((packed)) pte32pae_t;
/* LONG MODE 64 bit PAGE STRUCTURES */
typedef struct pml4e64 {
- uint_t present : 1;
- uint_t writable : 1;
- uint_t user_page : 1;
- uint_t write_through : 1;
- uint_t cache_disable : 1;
- uint_t accessed : 1;
- uint_t reserved : 1;
- uint_t zero : 2;
- uint_t vmm_info : 3;
- ullong_t pdp_base_addr : 40;
- uint_t available : 11;
- uint_t no_execute : 1;
+ uint_t present : 1;
+ uint_t writable : 1;
+ uint_t user_page : 1;
+ uint_t write_through : 1;
+ uint_t cache_disable : 1;
+ uint_t accessed : 1;
+ uint_t reserved : 1;
+ uint_t zero : 2;
+ uint_t vmm_info : 3;
+ ullong_t pdp_base_addr : 40;
+ uint_t available : 11;
+ uint_t no_execute : 1;
} __attribute__((packed)) pml4e64_t;
typedef struct pdpe64 {
- uint_t present : 1;
- uint_t writable : 1;
- uint_t user_page : 1;
- uint_t write_through : 1;
- uint_t cache_disable : 1;
- uint_t accessed : 1;
- uint_t avail : 1;
- uint_t large_page : 1;
- uint_t zero : 1;
- uint_t vmm_info : 3;
- ullong_t pd_base_addr : 40;
- uint_t available : 11;
- uint_t no_execute : 1;
+ uint_t present : 1;
+ uint_t writable : 1;
+ uint_t user_page : 1;
+ uint_t write_through : 1;
+ uint_t cache_disable : 1;
+ uint_t accessed : 1;
+ uint_t avail : 1;
+ uint_t large_page : 1;
+ uint_t zero : 1;
+ uint_t vmm_info : 3;
+ ullong_t pd_base_addr : 40;
+ uint_t available : 11;
+ uint_t no_execute : 1;
} __attribute__((packed)) pdpe64_t;
// We Don't support this
typedef struct pdpe64_1GB {
- uint_t present : 1;
- uint_t writable : 1;
- uint_t user_page : 1;
- uint_t write_through : 1;
- uint_t cache_disable : 1;
- uint_t accessed : 1;
- uint_t dirty : 1;
- uint_t large_page : 1;
- uint_t global_page : 1;
- uint_t vmm_info : 3;
- uint_t pat : 1;
- uint_t rsvd : 17;
- ullong_t page_base_addr : 22;
- uint_t available : 11;
- uint_t no_execute : 1;
+ uint_t present : 1;
+ uint_t writable : 1;
+ uint_t user_page : 1;
+ uint_t write_through : 1;
+ uint_t cache_disable : 1;
+ uint_t accessed : 1;
+ uint_t dirty : 1;
+ uint_t large_page : 1;
+ uint_t global_page : 1;
+ uint_t vmm_info : 3;
+ uint_t pat : 1;
+ uint_t rsvd : 17;
+ ullong_t page_base_addr : 22;
+ uint_t available : 11;
+ uint_t no_execute : 1;
} __attribute__((packed)) pdpe64_1GB_t;
typedef struct pde64 {
- uint_t present : 1;
- uint_t writable : 1;
- uint_t user_page : 1;
- uint_t write_through : 1;
- uint_t cache_disable : 1;
- uint_t accessed : 1;
- uint_t avail : 1;
- uint_t large_page : 1;
- uint_t global_page : 1;
- uint_t vmm_info : 3;
- ullong_t pt_base_addr : 40;
- uint_t available : 11;
- uint_t no_execute : 1;
+ uint_t present : 1;
+ uint_t writable : 1;
+ uint_t user_page : 1;
+ uint_t write_through : 1;
+ uint_t cache_disable : 1;
+ uint_t accessed : 1;
+ uint_t avail : 1;
+ uint_t large_page : 1;
+ uint_t global_page : 1;
+ uint_t vmm_info : 3;
+ ullong_t pt_base_addr : 40;
+ uint_t available : 11;
+ uint_t no_execute : 1;
} __attribute__((packed)) pde64_t;
typedef struct pde64_2MB {
- uint_t present : 1;
- uint_t writable : 1;
- uint_t user_page : 1;
- uint_t write_through : 1;
- uint_t cache_disable : 1;
- uint_t accessed : 1;
- uint_t dirty : 1;
- uint_t large_page : 1;
- uint_t global_page : 1;
- uint_t vmm_info : 3;
- uint_t pat : 1;
- uint_t rsvd : 8;
- ullong_t page_base_addr : 31;
- uint_t available : 11;
- uint_t no_execute : 1;
+ uint_t present : 1;
+ uint_t writable : 1;
+ uint_t user_page : 1;
+ uint_t write_through : 1;
+ uint_t cache_disable : 1;
+ uint_t accessed : 1;
+ uint_t dirty : 1;
+ uint_t large_page : 1;
+ uint_t global_page : 1;
+ uint_t vmm_info : 3;
+ uint_t pat : 1;
+ uint_t rsvd : 8;
+ ullong_t page_base_addr : 31;
+ uint_t available : 11;
+ uint_t no_execute : 1;
} __attribute__((packed)) pde64_2MB_t;
typedef struct pte64 {
- uint_t present : 1;
- uint_t writable : 1;
- uint_t user_page : 1;
- uint_t write_through : 1;
- uint_t cache_disable : 1;
- uint_t accessed : 1;
- uint_t dirty : 1;
- uint_t pte_attr : 1;
- uint_t global_page : 1;
- uint_t vmm_info : 3;
- ullong_t page_base_addr : 40;
- uint_t available : 11;
- uint_t no_execute : 1;
+ uint_t present : 1;
+ uint_t writable : 1;
+ uint_t user_page : 1;
+ uint_t write_through : 1;
+ uint_t cache_disable : 1;
+ uint_t accessed : 1;
+ uint_t dirty : 1;
+ uint_t pte_attr : 1;
+ uint_t global_page : 1;
+ uint_t vmm_info : 3;
+ ullong_t page_base_addr : 40;
+ uint_t available : 11;
+ uint_t no_execute : 1;
} __attribute__((packed)) pte64_t;
/* *************** */
typedef struct pf_error_code {
- uint_t present : 1; // if 0, fault due to page not present
- uint_t write : 1; // if 1, faulting access was a write
- uint_t user : 1; // if 1, faulting access was in user mode
- uint_t rsvd_access : 1; // if 1, fault from reading a 1 from a reserved field (?)
- uint_t ifetch : 1; // if 1, faulting access was an instr fetch (only with NX)
- uint_t rsvd : 27;
+ uint_t present : 1; // if 0, fault due to page not present
+ uint_t write : 1; // if 1, faulting access was a write
+ uint_t user : 1; // if 1, faulting access was in user mode
+ uint_t rsvd_access : 1; // if 1, fault from reading a 1 from a reserved field (?)
+ uint_t ifetch : 1; // if 1, faulting access was an instr fetch (only with NX)
+ uint_t rsvd : 27;
} __attribute__((packed)) pf_error_t;
struct v3_profiler {
- uint_t total_exits;
+ uint_t total_exits;
- ullong_t start_time;
- ullong_t end_time;
+ ullong_t start_time;
+ ullong_t end_time;
- uint_t guest_pf_cnt;
+ uint_t guest_pf_cnt;
- struct rb_root root;
+ struct rb_root root;
};
struct queue_entry {
- addr_t entry;
- struct list_head entry_list;
+ addr_t entry;
+ struct list_head entry_list;
};
struct gen_queue {
- uint_t num_entries;
- struct list_head entries;
+ uint_t num_entries;
+ struct list_head entries;
- // We really need to implement this....
- // void * lock;
+ // We really need to implement this....
+ // void * lock;
};
#undef offsetof
#define offsetof(TYPE, MEMBER) ((size_t) &((TYPE *)0)->MEMBER)
-#define container_of(ptr, type, member) ({ \
- const typeof( ((type *)0)->member ) *__mptr = (ptr); \
- (type *)( (char *)__mptr - offsetof(type,member) );})
+#define container_of(ptr, type, member) ({ \
+ const typeof( ((type *)0)->member ) *__mptr = (ptr); \
+ (type *)( (char *)__mptr - offsetof(type,member) );})
struct rb_node
{
- unsigned long rb_parent_color;
+ unsigned long rb_parent_color;
#define RB_RED 0
#define RB_BLACK 1
- struct rb_node *rb_right;
- struct rb_node *rb_left;
+ struct rb_node *rb_right;
+ struct rb_node *rb_left;
} __attribute__((aligned(sizeof(long))));
- /* The alignment might seem pointless, but allegedly CRIS needs it */
+/* The alignment might seem pointless, but allegedly CRIS needs it */
struct rb_root
{
- struct rb_node *rb_node;
+ struct rb_node *rb_node;
};
static inline void rb_set_parent(struct rb_node *rb, struct rb_node *p)
{
- rb->rb_parent_color = (rb->rb_parent_color & 3) | (unsigned long)p;
+ rb->rb_parent_color = (rb->rb_parent_color & 3) | (unsigned long)p;
}
static inline void rb_set_color(struct rb_node *rb, int color)
{
- rb->rb_parent_color = (rb->rb_parent_color & ~1) | color;
+ rb->rb_parent_color = (rb->rb_parent_color & ~1) | color;
}
#define RB_ROOT (struct rb_root) { NULL, }
static inline void rb_link_node(struct rb_node * node, struct rb_node * parent,
struct rb_node ** rb_link)
{
- node->rb_parent_color = (unsigned long )parent;
- node->rb_left = node->rb_right = NULL;
+ node->rb_parent_color = (unsigned long )parent;
+ node->rb_left = node->rb_right = NULL;
- *rb_link = node;
+ *rb_link = node;
}
#endif
struct v3_ringbuf {
- uchar_t * buf;
- uint_t size;
+ uchar_t * buf;
+ uint_t size;
- uint_t start;
- uint_t end;
- uint_t current_len;
+ uint_t start;
+ uint_t end;
+ uint_t current_len;
};
struct shadow_page_state {
- // virtualized control registers
- v3_reg_t guest_cr3;
- v3_reg_t guest_cr0;
+ // virtualized control registers
+ v3_reg_t guest_cr3;
+ v3_reg_t guest_cr0;
- // list of allocated shadow pages
- struct list_head page_list;
+ // list of allocated shadow pages
+ struct list_head page_list;
- /* SOON TO BE DEPRECATED */
- // Hash table that contains a mapping of guest pte addresses to host pte addresses
- struct hashtable * cached_ptes;
- addr_t cached_cr3;
+ /* SOON TO BE DEPRECATED */
+ // Hash table that contains a mapping of guest pte addresses to host pte addresses
+ struct hashtable * cached_ptes;
+ addr_t cached_cr3;
};
#ifdef __V3VEE__
-#define V3_Create_UDP_Socket() ({ \
- extern struct v3_socket_hooks * sock_hooks; \
- int sock = 0; \
- if ((sock_hooks) && (sock_hooks)->udp_socket) { \
- sock = (sock_hooks)->udp_socket(0,0); \
- } \
- sock; \
- })
+#define V3_Create_UDP_Socket() ({ \
+ extern struct v3_socket_hooks * sock_hooks; \
+ int sock = 0; \
+ if ((sock_hooks) && (sock_hooks)->udp_socket) { \
+ sock = (sock_hooks)->udp_socket(0,0); \
+ } \
+ sock; \
+ })
-#define V3_Create_TCP_Socket() ({ \
- extern struct v3_socket_hooks * sock_hooks; \
- int sock = 0; \
- if ((sock_hooks) && (sock_hooks)->tcp_socket) { \
- sock = (sock_hooks)->tcp_socket(0,0,0); \
- } \
- sock; \
- })
+#define V3_Create_TCP_Socket() ({ \
+ extern struct v3_socket_hooks * sock_hooks; \
+ int sock = 0; \
+ if ((sock_hooks) && (sock_hooks)->tcp_socket) { \
+ sock = (sock_hooks)->tcp_socket(0,0,0); \
+ } \
+ sock; \
+ })
-#define V3_Close_Socket(sock) \
- do { \
- extern struct v3_socket_hooks * sock_hooks; \
- if ((sock_hooks) && (sock_hooks)->close) { \
- (sock_hooks)->close(sock); \
- } \
- } while (0);
+#define V3_Close_Socket(sock) \
+ do { \
+ extern struct v3_socket_hooks * sock_hooks; \
+ if ((sock_hooks) && (sock_hooks)->close) { \
+ (sock_hooks)->close(sock); \
+ } \
+ } while (0);
#define V3_Bind_Socket(sock, port) ({ \
- extern struct v3_socket_hooks * sock_hooks; \
- int ret = -1; \
- if ((sock_hooks) && (sock_hooks)->bind_socket) { \
- ret = (sock_hooks)->bind_socket(sock, port); \
- } \
- ret; \
- })
+ extern struct v3_socket_hooks * sock_hooks; \
+ int ret = -1; \
+ if ((sock_hooks) && (sock_hooks)->bind_socket) { \
+ ret = (sock_hooks)->bind_socket(sock, port); \
+ } \
+ ret; \
+ })
-#define V3_Listen_Socket(sock, backlog) ({ \
- extern struct v3_socket_hooks * sock_hooks; \
- int ret = -1; \
- if ((sock_hooks) && (sock_hooks)->listen) { \
- ret = (sock_hooks)->listen(sock, backlog); \
- } \
- ret; \
- })
+#define V3_Listen_Socket(sock, backlog) ({ \
+ extern struct v3_socket_hooks * sock_hooks; \
+ int ret = -1; \
+ if ((sock_hooks) && (sock_hooks)->listen) { \
+ ret = (sock_hooks)->listen(sock, backlog); \
+ } \
+ ret; \
+ })
#define V3_Accept_Socket(sock, ip_ptr, port_ptr) ({ \
- extern struct v3_socket_hooks * sock_hooks; \
- int client_sock = 0; \
- if ((sock_hooks) && (sock_hooks)->accept) { \
- client_sock = (sock_hooks)->accept(sock, ip_ptr, port_ptr); \
- } \
- client_sock; \
- })
+ extern struct v3_socket_hooks * sock_hooks; \
+ int client_sock = 0; \
+ if ((sock_hooks) && (sock_hooks)->accept) { \
+ client_sock = (sock_hooks)->accept(sock, ip_ptr, port_ptr); \
+ } \
+ client_sock; \
+ })
-#define V3_Select_Socket(rset,wset,eset,tv) ({ \
- extern struct v3_socket_hooks * sock_hooks; \
- int ret = -1; \
- if ((sock_hooks) && (sock_hooks)->select) { \
- ret = (sock_hooks)->select(rset, wset, eset, tv); \
- } \
- ret; \
- })
+#define V3_Select_Socket(rset,wset,eset,tv) ({ \
+ extern struct v3_socket_hooks * sock_hooks; \
+ int ret = -1; \
+ if ((sock_hooks) && (sock_hooks)->select) { \
+ ret = (sock_hooks)->select(rset, wset, eset, tv); \
+ } \
+ ret; \
+ })
-#define V3_Connect_To_IP(sock, ip, port) ({ \
- extern struct v3_socket_hooks * sock_hooks; \
- int ret = -1; \
- if ((sock_hooks) && (sock_hooks)->connect_to_ip) { \
- ret = (sock_hooks)->connect_to_ip(sock, ip, port); \
- } \
- ret; \
- })
+#define V3_Connect_To_IP(sock, ip, port) ({ \
+ extern struct v3_socket_hooks * sock_hooks; \
+ int ret = -1; \
+ if ((sock_hooks) && (sock_hooks)->connect_to_ip) { \
+ ret = (sock_hooks)->connect_to_ip(sock, ip, port); \
+ } \
+ ret; \
+ })
#define V3_Connect_To_Host(sock, hostname, port) ({ \
- extern struct v3_socket_hooks * sock_hooks; \
- int ret = -1; \
- if ((sock_hooks) && (sock_hooks)->connect_to_host) { \
- ret = (sock_hooks)->connect_to_host(sock, hostname, port); \
- } \
- ret; \
- })
+ extern struct v3_socket_hooks * sock_hooks; \
+ int ret = -1; \
+ if ((sock_hooks) && (sock_hooks)->connect_to_host) { \
+ ret = (sock_hooks)->connect_to_host(sock, hostname, port); \
+ } \
+ ret; \
+ })
#define V3_Send(sock, buf, len) ({ \
- extern struct v3_socket_hooks * sock_hooks; \
- int ret = -1; \
- if ((sock_hooks) && (sock_hooks)->send) { \
- ret = (sock_hooks)->send(sock, buf, len); \
- } \
- ret; \
- })
+ extern struct v3_socket_hooks * sock_hooks; \
+ int ret = -1; \
+ if ((sock_hooks) && (sock_hooks)->send) { \
+ ret = (sock_hooks)->send(sock, buf, len); \
+ } \
+ ret; \
+ })
#define V3_Recv(sock, buf, len) ({ \
- extern struct v3_socket_hooks * sock_hooks; \
- int ret = -1; \
- if ((sock_hooks) && (sock_hooks)->recv) { \
- ret = (sock_hooks)->recv(sock, buf, len); \
- } \
- ret; \
- })
+ extern struct v3_socket_hooks * sock_hooks; \
+ int ret = -1; \
+ if ((sock_hooks) && (sock_hooks)->recv) { \
+ ret = (sock_hooks)->recv(sock, buf, len); \
+ } \
+ ret; \
+ })
#define V3_SendTo_Host(sock, hostname, port, buf, len) ({ \
- extern struct v3_socket_hooks * sock_hooks; \
- int ret = -1; \
- if ((sock_hooks) && (sock_hooks)->sendto_host) { \
- ret = (sock_hooks)->sendto_host(sock, hostname, port, buf, len); \
- } \
- ret; \
- })
+ extern struct v3_socket_hooks * sock_hooks; \
+ int ret = -1; \
+ if ((sock_hooks) && (sock_hooks)->sendto_host) { \
+ ret = (sock_hooks)->sendto_host(sock, hostname, port, buf, len); \
+ } \
+ ret; \
+ })
#define V3_SendTo_IP(sock, ip, port, buf, len) ({ \
- extern struct v3_socket_hooks * sock_hooks; \
- int ret = -1; \
- if ((sock_hooks) && (sock_hooks)->sendto_ip) { \
- ret = (sock_hooks)->sendto_ip(sock, ip, port, buf, len); \
- } \
- ret; \
- })
+ extern struct v3_socket_hooks * sock_hooks; \
+ int ret = -1; \
+ if ((sock_hooks) && (sock_hooks)->sendto_ip) { \
+ ret = (sock_hooks)->sendto_ip(sock, ip, port, buf, len); \
+ } \
+ ret; \
+ })
#define V3_RecvFrom_Host(sock, hostname, port, buf, len) ({ \
- extern struct v3_socket_hooks * sock_hooks; \
- int ret = -1; \
- if ((sock_hooks) && (sock_hooks)->recvfrom_host) { \
- ret = (sock_hooks)->recvfrom_host(sock, hostname, port, buf, len); \
- } \
- ret; \
- })
+ extern struct v3_socket_hooks * sock_hooks; \
+ int ret = -1; \
+ if ((sock_hooks) && (sock_hooks)->recvfrom_host) { \
+ ret = (sock_hooks)->recvfrom_host(sock, hostname, port, buf, len); \
+ } \
+ ret; \
+ })
#define V3_RecvFrom_IP(sock, ip, port, buf, len) ({ \
- extern struct v3_socket_hooks * sock_hooks; \
- int ret = -1; \
- if ((sock_hooks) && (sock_hooks)->recvfrom_ip) { \
- ret = (sock_hooks)->recvfrom_ip(sock, ip, port, buf, len); \
- } \
- ret; \
- })
+ extern struct v3_socket_hooks * sock_hooks; \
+ int ret = -1; \
+ if ((sock_hooks) && (sock_hooks)->recvfrom_ip) { \
+ ret = (sock_hooks)->recvfrom_ip(sock, ip, port, buf, len); \
+ } \
+ ret; \
+ })
struct v3_timeval {
- long tv_sec; /* seconds */
- long tv_usec; /* and microseconds */
+ long tv_sec; /* seconds */
+ long tv_usec; /* and microseconds */
};
#define V3_SOCK_SETSIZE 1000
typedef struct v3_sock_set {
- // This format needs to match the standard posix FD_SET format, so it can be cast
- unsigned char fd_bits [(V3_SOCK_SETSIZE + 7) / 8];
+ // This format needs to match the standard posix FD_SET format, so it can be cast
+ unsigned char fd_bits [(V3_SOCK_SETSIZE + 7) / 8];
} v3_sock_set;
struct v3_socket_hooks {
- // Socket creation routines
- int (*tcp_socket)(const int bufsize, const int nodelay, const int nonblocking);
- int (*udp_socket)(const int bufsize, const int nonblocking);
+ // Socket creation routines
+ int (*tcp_socket)(const int bufsize, const int nodelay, const int nonblocking);
+ int (*udp_socket)(const int bufsize, const int nonblocking);
- // Socket Destruction
- void (*close)(int sock);
+ // Socket Destruction
+ void (*close)(int sock);
- // Network Server Calls
- int (*bind_socket)(const int sock, const int port);
+ // Network Server Calls
+ int (*bind_socket)(const int sock, const int port);
- int (*listen)(const int sock, int backlog);
+ int (*listen)(const int sock, int backlog);
- int (*accept)(const int sock, unsigned int * remote_ip, unsigned int * port);
- // This going to suck
- int (*select)(struct v3_sock_set * rset, \
- struct v3_sock_set * wset, \
- struct v3_sock_set * eset, \
- struct v3_timeval tv);
-
- // Connect calls
- int (*connect_to_ip)(const int sock, const int hostip, const int port);
- int (*connect_to_host)(const int sock, const char * hostname, const int port);
-
- // TCP Data Transfer
- int (*send)(const int sock, const char * buf, const int len);
- int (*recv)(const int sock, char * buf, const int len);
+ int (*accept)(const int sock, unsigned int * remote_ip, unsigned int * port);
+ // This going to suck
+ int (*select)(struct v3_sock_set * rset, \
+ struct v3_sock_set * wset, \
+ struct v3_sock_set * eset, \
+ struct v3_timeval tv);
+
+ // Connect calls
+ int (*connect_to_ip)(const int sock, const int hostip, const int port);
+ int (*connect_to_host)(const int sock, const char * hostname, const int port);
+
+ // TCP Data Transfer
+ int (*send)(const int sock, const char * buf, const int len);
+ int (*recv)(const int sock, char * buf, const int len);
- // UDP Data Transfer
- int (*sendto_host)(const int sock, const char * hostname, const int port,
- const char * buf, const int len);
- int (*sendto_ip)(const int sock, const int ip_addr, const int port,
- const char * buf, const int len);
+ // UDP Data Transfer
+ int (*sendto_host)(const int sock, const char * hostname, const int port,
+ const char * buf, const int len);
+ int (*sendto_ip)(const int sock, const int ip_addr, const int port,
+ const char * buf, const int len);
- int (*recvfrom_host)(const int sock, const char * hostname, const int port,
- char * buf, const int len);
- int (*recvfrom_ip)(const int sock, const int ip_addr, const int port,
+ int (*recvfrom_host)(const int sock, const char * hostname, const int port,
char * buf, const int len);
+ int (*recvfrom_ip)(const int sock, const int ip_addr, const int port,
+ char * buf, const int len);
};
struct guest_info;
struct vm_time {
- uint32_t cpu_freq; // in kHZ
+ uint32_t cpu_freq; // in kHZ
- // Total number of guest run time cycles
- ullong_t guest_tsc;
+ // Total number of guest run time cycles
+ ullong_t guest_tsc;
- // Cache value to help calculate the guest_tsc
- ullong_t cached_host_tsc;
+ // Cache value to help calculate the guest_tsc
+ ullong_t cached_host_tsc;
- // The number of cycles pending for notification to the timers
- //ullong_t pending_cycles;
+ // The number of cycles pending for notification to the timers
+ //ullong_t pending_cycles;
- // Installed Timers
- uint_t num_timers;
- struct list_head timers;
+ // Installed Timers
+ uint_t num_timers;
+ struct list_head timers;
};
struct vm_timer_ops {
- void (*update_time)(ullong_t cpu_cycles, ullong_t cpu_freq, void * priv_data);
+ void (*update_time)(ullong_t cpu_cycles, ullong_t cpu_freq, void * priv_data);
};
struct vm_timer {
- void * private_data;
- struct vm_timer_ops * ops;
+ void * private_data;
+ struct vm_timer_ops * ops;
- struct list_head timer_link;
+ struct list_head timer_link;
};
typedef union reg_ex {
- ullong_t r_reg;
- struct {
- uint_t low;
- uint_t high;
- } e_reg;
+ ullong_t r_reg;
+ struct {
+ uint_t low;
+ uint_t high;
+ } e_reg;
} reg_ex_t;
// These are the GPRs layed out according to 'pusha'
struct VMM_GPRs {
- uint_t edi;
- uint_t esi;
- uint_t ebp;
- uint_t esp;
- uint_t ebx;
- uint_t edx;
- uint_t ecx;
- uint_t eax;
+ uint_t edi;
+ uint_t esi;
+ uint_t ebp;
+ uint_t esp;
+ uint_t ebx;
+ uint_t edx;
+ uint_t ecx;
+ uint_t eax;
};
#define rdtsc(low,high) \
- __asm__ __volatile__("rdtsc" : "=a" (low), "=d" (high))
+ __asm__ __volatile__("rdtsc" : "=a" (low), "=d" (high))
#define rdtscl(low) \
- __asm__ __volatile__("rdtsc" : "=a" (low) : : "edx")
+ __asm__ __volatile__("rdtsc" : "=a" (low) : : "edx")
-#define rdtscll(val) \
- do { \
- uint64_t tsc; \
- uint32_t a, d; \
- asm volatile("rdtsc" : "=a" (a), "=d" (d)); \
- *(uint32_t *)&(tsc) = a; \
- *(uint32_t *)(((uchar_t *)&tsc) + 4) = d; \
- val = tsc; \
- } while (0)
+#define rdtscll(val) \
+ do { \
+ uint64_t tsc; \
+ uint32_t a, d; \
+ asm volatile("rdtsc" : "=a" (a), "=d" (d)); \
+ *(uint32_t *)&(tsc) = a; \
+ *(uint32_t *)(((uchar_t *)&tsc) + 4) = d; \
+ val = tsc; \
+ } while (0)
/*
-#if __V3_32BIT__
+ #if __V3_32BIT__
-#define rdtscll(val) \
- __asm__ __volatile__("rdtsc" : "=A" (val))
+ #define rdtscll(val) \
+ __asm__ __volatile__("rdtsc" : "=A" (val))
-#elif __V3_64BIT__
+ #elif __V3_64BIT__
-#define rdtscll(val) do { \
- unsigned int a,d; \
- asm volatile("rdtsc" : "=a" (a), "=d" (d)); \
- (val) = ((unsigned long)a) | (((unsigned long)d)<<32); \
+ #define rdtscll(val) do { \
+ unsigned int a,d; \
+ asm volatile("rdtsc" : "=a" (a), "=d" (d)); \
+ (val) = ((unsigned long)a) | (((unsigned long)d)<<32); \
} while(0)
-#endif
+ #endif
*/
#ifdef __V3_64BIT__
-#define do_divll(n, base) ({ \
- uint64_t __rem = 0; \
- uint64_t __num = 0; \
- while (n > base) { \
- __num++; \
- n -= base; \
- } \
- __rem = n; \
- n = __num; \
- __rem; \
- })
+#define do_divll(n, base) ({ \
+ uint64_t __rem = 0; \
+ uint64_t __num = 0; \
+ while (n > base) { \
+ __num++; \
+ n -= base; \
+ } \
+ __rem = n; \
+ n = __num; \
+ __rem; \
+ })
//#define do_divll do_div
* This ends up being the most efficient "calling
* convention" on x86.
*/
-#define do_div(n,base) ({ \
- unsigned long __upper, __low, __high, __mod, __base; \
- __base = (base); \
- asm("":"=a" (__low), "=d" (__high):"A" (n)); \
- __upper = __high; \
- if (__high) { \
- __upper = __high % (__base); \
- __high = __high / (__base); \
- } \
- asm("divl %2":"=a" (__low), "=d" (__mod):"rm" (__base), "0" (__low), "1" (__upper)); \
- asm("":"=A" (n):"a" (__low),"d" (__high)); \
- __mod; \
- })
+#define do_div(n,base) ({ \
+ unsigned long __upper, __low, __high, __mod, __base; \
+ __base = (base); \
+ asm("":"=a" (__low), "=d" (__high):"A" (n)); \
+ __upper = __high; \
+ if (__high) { \
+ __upper = __high % (__base); \
+ __high = __high / (__base); \
+ } \
+ asm("divl %2":"=a" (__low), "=d" (__mod):"rm" (__base), "0" (__low), "1" (__upper)); \
+ asm("":"=A" (n):"a" (__low),"d" (__high)); \
+ __mod; \
+ })
*
* NOTE: This absolutely sucks... there has to be a better way....
*/
-#define do_divll(n, base) ({ \
- ullong_t __rem = 0; \
- ullong_t __num = 0; \
- while (n > base) { \
- __num++; \
- n -= base; \
- } \
- __rem = n; \
- n = __num; \
- __rem; \
- })
+#define do_divll(n, base) ({ \
+ ullong_t __rem = 0; \
+ ullong_t __num = 0; \
+ while (n > base) { \
+ __num++; \
+ n -= base; \
+ } \
+ __rem = n; \
+ n = __num; \
+ __rem; \
+ })
#endif