aboutsummaryrefslogtreecommitdiff
path: root/target-i386/svm.h
diff options
context:
space:
mode:
authorbellard <bellard@c046a42c-6fe2-441c-8c8c-71466251a162>2008-05-28 16:16:54 +0000
committerbellard <bellard@c046a42c-6fe2-441c-8c8c-71466251a162>2008-05-28 16:16:54 +0000
commit872929aa59cba19fd83b98f87929ccda12a2cbbb (patch)
treec48d33acaf7c44d48c35507fba462b84f1022149 /target-i386/svm.h
parent893f986502196aeb43d176161179c3ff22a7e0a8 (diff)
SVM rework
git-svn-id: svn://svn.savannah.nongnu.org/qemu/trunk@4605 c046a42c-6fe2-441c-8c8c-71466251a162
Diffstat (limited to 'target-i386/svm.h')
-rw-r--r--target-i386/svm.h299
1 files changed, 87 insertions, 212 deletions
diff --git a/target-i386/svm.h b/target-i386/svm.h
index add52fc986..6d86890818 100644
--- a/target-i386/svm.h
+++ b/target-i386/svm.h
@@ -1,91 +1,6 @@
#ifndef __SVM_H
#define __SVM_H
-enum {
- /* We shift all the intercept bits so we can OR them with the
- TB flags later on */
- INTERCEPT_INTR = HF_HIF_SHIFT,
- INTERCEPT_NMI,
- INTERCEPT_SMI,
- INTERCEPT_INIT,
- INTERCEPT_VINTR,
- INTERCEPT_SELECTIVE_CR0,
- INTERCEPT_STORE_IDTR,
- INTERCEPT_STORE_GDTR,
- INTERCEPT_STORE_LDTR,
- INTERCEPT_STORE_TR,
- INTERCEPT_LOAD_IDTR,
- INTERCEPT_LOAD_GDTR,
- INTERCEPT_LOAD_LDTR,
- INTERCEPT_LOAD_TR,
- INTERCEPT_RDTSC,
- INTERCEPT_RDPMC,
- INTERCEPT_PUSHF,
- INTERCEPT_POPF,
- INTERCEPT_CPUID,
- INTERCEPT_RSM,
- INTERCEPT_IRET,
- INTERCEPT_INTn,
- INTERCEPT_INVD,
- INTERCEPT_PAUSE,
- INTERCEPT_HLT,
- INTERCEPT_INVLPG,
- INTERCEPT_INVLPGA,
- INTERCEPT_IOIO_PROT,
- INTERCEPT_MSR_PROT,
- INTERCEPT_TASK_SWITCH,
- INTERCEPT_FERR_FREEZE,
- INTERCEPT_SHUTDOWN,
- INTERCEPT_VMRUN,
- INTERCEPT_VMMCALL,
- INTERCEPT_VMLOAD,
- INTERCEPT_VMSAVE,
- INTERCEPT_STGI,
- INTERCEPT_CLGI,
- INTERCEPT_SKINIT,
- INTERCEPT_RDTSCP,
- INTERCEPT_ICEBP,
- INTERCEPT_WBINVD,
-};
-/* This is not really an intercept but rather a placeholder to
- show that we are in an SVM (just like a hidden flag, but keeps the
- TBs clean) */
-#define INTERCEPT_SVM 63
-#define INTERCEPT_SVM_MASK (1ULL << INTERCEPT_SVM)
-
-struct __attribute__ ((__packed__)) vmcb_control_area {
- uint16_t intercept_cr_read;
- uint16_t intercept_cr_write;
- uint16_t intercept_dr_read;
- uint16_t intercept_dr_write;
- uint32_t intercept_exceptions;
- uint64_t intercept;
- uint8_t reserved_1[44];
- uint64_t iopm_base_pa;
- uint64_t msrpm_base_pa;
- uint64_t tsc_offset;
- uint32_t asid;
- uint8_t tlb_ctl;
- uint8_t reserved_2[3];
- uint32_t int_ctl;
- uint32_t int_vector;
- uint32_t int_state;
- uint8_t reserved_3[4];
- uint64_t exit_code;
- uint64_t exit_info_1;
- uint64_t exit_info_2;
- uint32_t exit_int_info;
- uint32_t exit_int_info_err;
- uint64_t nested_ctl;
- uint8_t reserved_4[16];
- uint32_t event_inj;
- uint32_t event_inj_err;
- uint64_t nested_cr3;
- uint64_t lbr_ctl;
- uint8_t reserved_5[832];
-};
-
-
#define TLB_CONTROL_DO_NOTHING 0
#define TLB_CONTROL_FLUSH_ALL_ASID 1
@@ -116,104 +31,6 @@ struct __attribute__ ((__packed__)) vmcb_control_area {
#define SVM_IOIO_SIZE_MASK (7 << SVM_IOIO_SIZE_SHIFT)
#define SVM_IOIO_ASIZE_MASK (7 << SVM_IOIO_ASIZE_SHIFT)
-struct __attribute__ ((__packed__)) vmcb_seg {
- uint16_t selector;
- uint16_t attrib;
- uint32_t limit;
- uint64_t base;
-};
-
-struct __attribute__ ((__packed__)) vmcb_save_area {
- struct vmcb_seg es;
- struct vmcb_seg cs;
- struct vmcb_seg ss;
- struct vmcb_seg ds;
- struct vmcb_seg fs;
- struct vmcb_seg gs;
- struct vmcb_seg gdtr;
- struct vmcb_seg ldtr;
- struct vmcb_seg idtr;
- struct vmcb_seg tr;
- uint8_t reserved_1[43];
- uint8_t cpl;
- uint8_t reserved_2[4];
- uint64_t efer;
- uint8_t reserved_3[112];
- uint64_t cr4;
- uint64_t cr3;
- uint64_t cr0;
- uint64_t dr7;
- uint64_t dr6;
- uint64_t rflags;
- uint64_t rip;
- uint8_t reserved_4[88];
- uint64_t rsp;
- uint8_t reserved_5[24];
- uint64_t rax;
- uint64_t star;
- uint64_t lstar;
- uint64_t cstar;
- uint64_t sfmask;
- uint64_t kernel_gs_base;
- uint64_t sysenter_cs;
- uint64_t sysenter_esp;
- uint64_t sysenter_eip;
- uint64_t cr2;
- /* qemu: cr8 added to reuse this as hsave */
- uint64_t cr8;
- uint8_t reserved_6[32 - 8]; /* originally 32 */
- uint64_t g_pat;
- uint64_t dbgctl;
- uint64_t br_from;
- uint64_t br_to;
- uint64_t last_excp_from;
- uint64_t last_excp_to;
-};
-
-struct __attribute__ ((__packed__)) vmcb {
- struct vmcb_control_area control;
- struct vmcb_save_area save;
-};
-
-#define SVM_CPUID_FEATURE_SHIFT 2
-#define SVM_CPUID_FUNC 0x8000000a
-
-#define MSR_EFER_SVME_MASK (1ULL << 12)
-
-#define SVM_SELECTOR_S_SHIFT 4
-#define SVM_SELECTOR_DPL_SHIFT 5
-#define SVM_SELECTOR_P_SHIFT 7
-#define SVM_SELECTOR_AVL_SHIFT 8
-#define SVM_SELECTOR_L_SHIFT 9
-#define SVM_SELECTOR_DB_SHIFT 10
-#define SVM_SELECTOR_G_SHIFT 11
-
-#define SVM_SELECTOR_TYPE_MASK (0xf)
-#define SVM_SELECTOR_S_MASK (1 << SVM_SELECTOR_S_SHIFT)
-#define SVM_SELECTOR_DPL_MASK (3 << SVM_SELECTOR_DPL_SHIFT)
-#define SVM_SELECTOR_P_MASK (1 << SVM_SELECTOR_P_SHIFT)
-#define SVM_SELECTOR_AVL_MASK (1 << SVM_SELECTOR_AVL_SHIFT)
-#define SVM_SELECTOR_L_MASK (1 << SVM_SELECTOR_L_SHIFT)
-#define SVM_SELECTOR_DB_MASK (1 << SVM_SELECTOR_DB_SHIFT)
-#define SVM_SELECTOR_G_MASK (1 << SVM_SELECTOR_G_SHIFT)
-
-#define SVM_SELECTOR_WRITE_MASK (1 << 1)
-#define SVM_SELECTOR_READ_MASK SVM_SELECTOR_WRITE_MASK
-#define SVM_SELECTOR_CODE_MASK (1 << 3)
-
-#define INTERCEPT_CR0_MASK 1
-#define INTERCEPT_CR3_MASK (1 << 3)
-#define INTERCEPT_CR4_MASK (1 << 4)
-
-#define INTERCEPT_DR0_MASK 1
-#define INTERCEPT_DR1_MASK (1 << 1)
-#define INTERCEPT_DR2_MASK (1 << 2)
-#define INTERCEPT_DR3_MASK (1 << 3)
-#define INTERCEPT_DR4_MASK (1 << 4)
-#define INTERCEPT_DR5_MASK (1 << 5)
-#define INTERCEPT_DR6_MASK (1 << 6)
-#define INTERCEPT_DR7_MASK (1 << 7)
-
#define SVM_EVTINJ_VEC_MASK 0xff
#define SVM_EVTINJ_TYPE_SHIFT 8
@@ -313,37 +130,95 @@ struct __attribute__ ((__packed__)) vmcb {
#define SVM_CR0_SELECTIVE_MASK (1 << 3 | 1) /* TS and MP */
-#define SVM_VMLOAD ".byte 0x0f, 0x01, 0xda"
-#define SVM_VMRUN ".byte 0x0f, 0x01, 0xd8"
-#define SVM_VMSAVE ".byte 0x0f, 0x01, 0xdb"
-#define SVM_CLGI ".byte 0x0f, 0x01, 0xdd"
-#define SVM_STGI ".byte 0x0f, 0x01, 0xdc"
-#define SVM_INVLPGA ".byte 0x0f, 0x01, 0xdf"
-
-/* function references */
-
-#define INTERCEPTED(mask) (env->intercept & mask)
-#define INTERCEPTEDw(var, mask) (env->intercept ## var & mask)
-#define INTERCEPTEDl(var, mask) (env->intercept ## var & mask)
+struct __attribute__ ((__packed__)) vmcb_control_area {
+ uint16_t intercept_cr_read;
+ uint16_t intercept_cr_write;
+ uint16_t intercept_dr_read;
+ uint16_t intercept_dr_write;
+ uint32_t intercept_exceptions;
+ uint64_t intercept;
+ uint8_t reserved_1[44];
+ uint64_t iopm_base_pa;
+ uint64_t msrpm_base_pa;
+ uint64_t tsc_offset;
+ uint32_t asid;
+ uint8_t tlb_ctl;
+ uint8_t reserved_2[3];
+ uint32_t int_ctl;
+ uint32_t int_vector;
+ uint32_t int_state;
+ uint8_t reserved_3[4];
+ uint64_t exit_code;
+ uint64_t exit_info_1;
+ uint64_t exit_info_2;
+ uint32_t exit_int_info;
+ uint32_t exit_int_info_err;
+ uint64_t nested_ctl;
+ uint8_t reserved_4[16];
+ uint32_t event_inj;
+ uint32_t event_inj_err;
+ uint64_t nested_cr3;
+ uint64_t lbr_ctl;
+ uint8_t reserved_5[832];
+};
-#define SVM_LOAD_SEG(addr, seg_index, seg) \
- cpu_x86_load_seg_cache(env, \
- R_##seg_index, \
- lduw_phys(addr + offsetof(struct vmcb, save.seg.selector)),\
- ldq_phys(addr + offsetof(struct vmcb, save.seg.base)),\
- ldl_phys(addr + offsetof(struct vmcb, save.seg.limit)),\
- vmcb2cpu_attrib(lduw_phys(addr + offsetof(struct vmcb, save.seg.attrib)), ldq_phys(addr + offsetof(struct vmcb, save.seg.base)), ldl_phys(addr + offsetof(struct vmcb, save.seg.limit))))
+struct __attribute__ ((__packed__)) vmcb_seg {
+ uint16_t selector;
+ uint16_t attrib;
+ uint32_t limit;
+ uint64_t base;
+};
-#define SVM_LOAD_SEG2(addr, seg_qemu, seg_vmcb) \
- env->seg_qemu.selector = lduw_phys(addr + offsetof(struct vmcb, save.seg_vmcb.selector)); \
- env->seg_qemu.base = ldq_phys(addr + offsetof(struct vmcb, save.seg_vmcb.base)); \
- env->seg_qemu.limit = ldl_phys(addr + offsetof(struct vmcb, save.seg_vmcb.limit)); \
- env->seg_qemu.flags = vmcb2cpu_attrib(lduw_phys(addr + offsetof(struct vmcb, save.seg_vmcb.attrib)), env->seg_qemu.base, env->seg_qemu.limit)
+struct __attribute__ ((__packed__)) vmcb_save_area {
+ struct vmcb_seg es;
+ struct vmcb_seg cs;
+ struct vmcb_seg ss;
+ struct vmcb_seg ds;
+ struct vmcb_seg fs;
+ struct vmcb_seg gs;
+ struct vmcb_seg gdtr;
+ struct vmcb_seg ldtr;
+ struct vmcb_seg idtr;
+ struct vmcb_seg tr;
+ uint8_t reserved_1[43];
+ uint8_t cpl;
+ uint8_t reserved_2[4];
+ uint64_t efer;
+ uint8_t reserved_3[112];
+ uint64_t cr4;
+ uint64_t cr3;
+ uint64_t cr0;
+ uint64_t dr7;
+ uint64_t dr6;
+ uint64_t rflags;
+ uint64_t rip;
+ uint8_t reserved_4[88];
+ uint64_t rsp;
+ uint8_t reserved_5[24];
+ uint64_t rax;
+ uint64_t star;
+ uint64_t lstar;
+ uint64_t cstar;
+ uint64_t sfmask;
+ uint64_t kernel_gs_base;
+ uint64_t sysenter_cs;
+ uint64_t sysenter_esp;
+ uint64_t sysenter_eip;
+ uint64_t cr2;
+ /* qemu: cr8 added to reuse this as hsave */
+ uint64_t cr8;
+ uint8_t reserved_6[32 - 8]; /* originally 32 */
+ uint64_t g_pat;
+ uint64_t dbgctl;
+ uint64_t br_from;
+ uint64_t br_to;
+ uint64_t last_excp_from;
+ uint64_t last_excp_to;
+};
-#define SVM_SAVE_SEG(addr, seg_qemu, seg_vmcb) \
- stw_phys(addr + offsetof(struct vmcb, save.seg_vmcb.selector), env->seg_qemu.selector); \
- stq_phys(addr + offsetof(struct vmcb, save.seg_vmcb.base), env->seg_qemu.base); \
- stl_phys(addr + offsetof(struct vmcb, save.seg_vmcb.limit), env->seg_qemu.limit); \
- stw_phys(addr + offsetof(struct vmcb, save.seg_vmcb.attrib), cpu2vmcb_attrib(env->seg_qemu.flags))
+struct __attribute__ ((__packed__)) vmcb {
+ struct vmcb_control_area control;
+ struct vmcb_save_area save;
+};
#endif