Annotation of qemu/target-i386/svm.h, revision 1.1

1.1     ! root        1: #ifndef __SVM_H
        !             2: #define __SVM_H
        !             3: 
        !             4: enum {
        !             5:         /* We shift all the intercept bits so we can OR them with the
        !             6:            TB flags later on */
        !             7:        INTERCEPT_INTR = HF_HIF_SHIFT,
        !             8:        INTERCEPT_NMI,
        !             9:        INTERCEPT_SMI,
        !            10:        INTERCEPT_INIT,
        !            11:        INTERCEPT_VINTR,
        !            12:        INTERCEPT_SELECTIVE_CR0,
        !            13:        INTERCEPT_STORE_IDTR,
        !            14:        INTERCEPT_STORE_GDTR,
        !            15:        INTERCEPT_STORE_LDTR,
        !            16:        INTERCEPT_STORE_TR,
        !            17:        INTERCEPT_LOAD_IDTR,
        !            18:        INTERCEPT_LOAD_GDTR,
        !            19:        INTERCEPT_LOAD_LDTR,
        !            20:        INTERCEPT_LOAD_TR,
        !            21:        INTERCEPT_RDTSC,
        !            22:        INTERCEPT_RDPMC,
        !            23:        INTERCEPT_PUSHF,
        !            24:        INTERCEPT_POPF,
        !            25:        INTERCEPT_CPUID,
        !            26:        INTERCEPT_RSM,
        !            27:        INTERCEPT_IRET,
        !            28:        INTERCEPT_INTn,
        !            29:        INTERCEPT_INVD,
        !            30:        INTERCEPT_PAUSE,
        !            31:        INTERCEPT_HLT,
        !            32:        INTERCEPT_INVLPG,
        !            33:        INTERCEPT_INVLPGA,
        !            34:        INTERCEPT_IOIO_PROT,
        !            35:        INTERCEPT_MSR_PROT,
        !            36:        INTERCEPT_TASK_SWITCH,
        !            37:        INTERCEPT_FERR_FREEZE,
        !            38:        INTERCEPT_SHUTDOWN,
        !            39:        INTERCEPT_VMRUN,
        !            40:        INTERCEPT_VMMCALL,
        !            41:        INTERCEPT_VMLOAD,
        !            42:        INTERCEPT_VMSAVE,
        !            43:        INTERCEPT_STGI,
        !            44:        INTERCEPT_CLGI,
        !            45:        INTERCEPT_SKINIT,
        !            46:        INTERCEPT_RDTSCP,
        !            47:        INTERCEPT_ICEBP,
        !            48:        INTERCEPT_WBINVD,
        !            49: };
        !            50: /* This is not really an intercept but rather a placeholder to
        !            51:    show that we are in an SVM (just like a hidden flag, but keeps the
        !            52:    TBs clean) */
        !            53: #define INTERCEPT_SVM 63
        !            54: #define INTERCEPT_SVM_MASK (1ULL << INTERCEPT_SVM)
        !            55: 
        !            56: struct __attribute__ ((__packed__)) vmcb_control_area {
        !            57:        uint16_t intercept_cr_read;
        !            58:        uint16_t intercept_cr_write;
        !            59:        uint16_t intercept_dr_read;
        !            60:        uint16_t intercept_dr_write;
        !            61:        uint32_t intercept_exceptions;
        !            62:        uint64_t intercept;
        !            63:        uint8_t reserved_1[44];
        !            64:        uint64_t iopm_base_pa;
        !            65:        uint64_t msrpm_base_pa;
        !            66:        uint64_t tsc_offset;
        !            67:        uint32_t asid;
        !            68:        uint8_t tlb_ctl;
        !            69:        uint8_t reserved_2[3];
        !            70:        uint32_t int_ctl;
        !            71:        uint32_t int_vector;
        !            72:        uint32_t int_state;
        !            73:        uint8_t reserved_3[4];
        !            74:        uint32_t exit_code;
        !            75:        uint32_t exit_code_hi;
        !            76:        uint64_t exit_info_1;
        !            77:        uint64_t exit_info_2;
        !            78:        uint32_t exit_int_info;
        !            79:        uint32_t exit_int_info_err;
        !            80:        uint64_t nested_ctl;
        !            81:        uint8_t reserved_4[16];
        !            82:        uint32_t event_inj;
        !            83:        uint32_t event_inj_err;
        !            84:        uint64_t nested_cr3;
        !            85:        uint64_t lbr_ctl;
        !            86:        uint8_t reserved_5[832];
        !            87: };
        !            88: 
        !            89: 
        !            90: #define TLB_CONTROL_DO_NOTHING 0
        !            91: #define TLB_CONTROL_FLUSH_ALL_ASID 1
        !            92: 
        !            93: #define V_TPR_MASK 0x0f
        !            94: 
        !            95: #define V_IRQ_SHIFT 8
        !            96: #define V_IRQ_MASK (1 << V_IRQ_SHIFT)
        !            97: 
        !            98: #define V_INTR_PRIO_SHIFT 16
        !            99: #define V_INTR_PRIO_MASK (0x0f << V_INTR_PRIO_SHIFT)
        !           100: 
        !           101: #define V_IGN_TPR_SHIFT 20
        !           102: #define V_IGN_TPR_MASK (1 << V_IGN_TPR_SHIFT)
        !           103: 
        !           104: #define V_INTR_MASKING_SHIFT 24
        !           105: #define V_INTR_MASKING_MASK (1 << V_INTR_MASKING_SHIFT)
        !           106: 
        !           107: #define SVM_INTERRUPT_SHADOW_MASK 1
        !           108: 
        !           109: #define SVM_IOIO_STR_SHIFT 2
        !           110: #define SVM_IOIO_REP_SHIFT 3
        !           111: #define SVM_IOIO_SIZE_SHIFT 4
        !           112: #define SVM_IOIO_ASIZE_SHIFT 7
        !           113: 
        !           114: #define SVM_IOIO_TYPE_MASK 1
        !           115: #define SVM_IOIO_STR_MASK (1 << SVM_IOIO_STR_SHIFT)
        !           116: #define SVM_IOIO_REP_MASK (1 << SVM_IOIO_REP_SHIFT)
        !           117: #define SVM_IOIO_SIZE_MASK (7 << SVM_IOIO_SIZE_SHIFT)
        !           118: #define SVM_IOIO_ASIZE_MASK (7 << SVM_IOIO_ASIZE_SHIFT)
        !           119: 
        !           120: struct __attribute__ ((__packed__)) vmcb_seg {
        !           121:        uint16_t selector;
        !           122:        uint16_t attrib;
        !           123:        uint32_t limit;
        !           124:        uint64_t base;
        !           125: };
        !           126: 
        !           127: struct __attribute__ ((__packed__)) vmcb_save_area {
        !           128:        struct vmcb_seg es;
        !           129:        struct vmcb_seg cs;
        !           130:        struct vmcb_seg ss;
        !           131:        struct vmcb_seg ds;
        !           132:        struct vmcb_seg fs;
        !           133:        struct vmcb_seg gs;
        !           134:        struct vmcb_seg gdtr;
        !           135:        struct vmcb_seg ldtr;
        !           136:        struct vmcb_seg idtr;
        !           137:        struct vmcb_seg tr;
        !           138:        uint8_t reserved_1[43];
        !           139:        uint8_t cpl;
        !           140:        uint8_t reserved_2[4];
        !           141:        uint64_t efer;
        !           142:        uint8_t reserved_3[112];
        !           143:        uint64_t cr4;
        !           144:        uint64_t cr3;
        !           145:        uint64_t cr0;
        !           146:        uint64_t dr7;
        !           147:        uint64_t dr6;
        !           148:        uint64_t rflags;
        !           149:        uint64_t rip;
        !           150:        uint8_t reserved_4[88];
        !           151:        uint64_t rsp;
        !           152:        uint8_t reserved_5[24];
        !           153:        uint64_t rax;
        !           154:        uint64_t star;
        !           155:        uint64_t lstar;
        !           156:        uint64_t cstar;
        !           157:        uint64_t sfmask;
        !           158:        uint64_t kernel_gs_base;
        !           159:        uint64_t sysenter_cs;
        !           160:        uint64_t sysenter_esp;
        !           161:        uint64_t sysenter_eip;
        !           162:        uint64_t cr2;
        !           163:        /* qemu: cr8 added to reuse this as hsave */
        !           164:        uint64_t cr8;
        !           165:        uint8_t reserved_6[32 - 8]; /* originally 32 */
        !           166:        uint64_t g_pat;
        !           167:        uint64_t dbgctl;
        !           168:        uint64_t br_from;
        !           169:        uint64_t br_to;
        !           170:        uint64_t last_excp_from;
        !           171:        uint64_t last_excp_to;
        !           172: };
        !           173: 
        !           174: struct __attribute__ ((__packed__)) vmcb {
        !           175:        struct vmcb_control_area control;
        !           176:        struct vmcb_save_area save;
        !           177: };
        !           178: 
        !           179: #define SVM_CPUID_FEATURE_SHIFT 2
        !           180: #define SVM_CPUID_FUNC 0x8000000a
        !           181: 
        !           182: #define MSR_EFER_SVME_MASK (1ULL << 12)
        !           183: 
        !           184: #define SVM_SELECTOR_S_SHIFT 4
        !           185: #define SVM_SELECTOR_DPL_SHIFT 5
        !           186: #define SVM_SELECTOR_P_SHIFT 7
        !           187: #define SVM_SELECTOR_AVL_SHIFT 8
        !           188: #define SVM_SELECTOR_L_SHIFT 9
        !           189: #define SVM_SELECTOR_DB_SHIFT 10
        !           190: #define SVM_SELECTOR_G_SHIFT 11
        !           191: 
        !           192: #define SVM_SELECTOR_TYPE_MASK (0xf)
        !           193: #define SVM_SELECTOR_S_MASK (1 << SVM_SELECTOR_S_SHIFT)
        !           194: #define SVM_SELECTOR_DPL_MASK (3 << SVM_SELECTOR_DPL_SHIFT)
        !           195: #define SVM_SELECTOR_P_MASK (1 << SVM_SELECTOR_P_SHIFT)
        !           196: #define SVM_SELECTOR_AVL_MASK (1 << SVM_SELECTOR_AVL_SHIFT)
        !           197: #define SVM_SELECTOR_L_MASK (1 << SVM_SELECTOR_L_SHIFT)
        !           198: #define SVM_SELECTOR_DB_MASK (1 << SVM_SELECTOR_DB_SHIFT)
        !           199: #define SVM_SELECTOR_G_MASK (1 << SVM_SELECTOR_G_SHIFT)
        !           200: 
        !           201: #define SVM_SELECTOR_WRITE_MASK (1 << 1)
        !           202: #define SVM_SELECTOR_READ_MASK SVM_SELECTOR_WRITE_MASK
        !           203: #define SVM_SELECTOR_CODE_MASK (1 << 3)
        !           204: 
        !           205: #define INTERCEPT_CR0_MASK 1
        !           206: #define INTERCEPT_CR3_MASK (1 << 3)
        !           207: #define INTERCEPT_CR4_MASK (1 << 4)
        !           208: 
        !           209: #define INTERCEPT_DR0_MASK 1
        !           210: #define INTERCEPT_DR1_MASK (1 << 1)
        !           211: #define INTERCEPT_DR2_MASK (1 << 2)
        !           212: #define INTERCEPT_DR3_MASK (1 << 3)
        !           213: #define INTERCEPT_DR4_MASK (1 << 4)
        !           214: #define INTERCEPT_DR5_MASK (1 << 5)
        !           215: #define INTERCEPT_DR6_MASK (1 << 6)
        !           216: #define INTERCEPT_DR7_MASK (1 << 7)
        !           217: 
        !           218: #define SVM_EVTINJ_VEC_MASK 0xff
        !           219: 
        !           220: #define SVM_EVTINJ_TYPE_SHIFT 8
        !           221: #define SVM_EVTINJ_TYPE_MASK (7 << SVM_EVTINJ_TYPE_SHIFT)
        !           222: 
        !           223: #define SVM_EVTINJ_TYPE_INTR (0 << SVM_EVTINJ_TYPE_SHIFT)
        !           224: #define SVM_EVTINJ_TYPE_NMI (2 << SVM_EVTINJ_TYPE_SHIFT)
        !           225: #define SVM_EVTINJ_TYPE_EXEPT (3 << SVM_EVTINJ_TYPE_SHIFT)
        !           226: #define SVM_EVTINJ_TYPE_SOFT (4 << SVM_EVTINJ_TYPE_SHIFT)
        !           227: 
        !           228: #define SVM_EVTINJ_VALID (1 << 31)
        !           229: #define SVM_EVTINJ_VALID_ERR (1 << 11)
        !           230: 
        !           231: #define SVM_EXITINTINFO_VEC_MASK SVM_EVTINJ_VEC_MASK
        !           232: 
        !           233: #define        SVM_EXITINTINFO_TYPE_INTR SVM_EVTINJ_TYPE_INTR
        !           234: #define        SVM_EXITINTINFO_TYPE_NMI SVM_EVTINJ_TYPE_NMI
        !           235: #define        SVM_EXITINTINFO_TYPE_EXEPT SVM_EVTINJ_TYPE_EXEPT
        !           236: #define        SVM_EXITINTINFO_TYPE_SOFT SVM_EVTINJ_TYPE_SOFT
        !           237: 
        !           238: #define SVM_EXITINTINFO_VALID SVM_EVTINJ_VALID
        !           239: #define SVM_EXITINTINFO_VALID_ERR SVM_EVTINJ_VALID_ERR
        !           240: 
        !           241: #define        SVM_EXIT_READ_CR0       0x000
        !           242: #define        SVM_EXIT_READ_CR3       0x003
        !           243: #define        SVM_EXIT_READ_CR4       0x004
        !           244: #define        SVM_EXIT_READ_CR8       0x008
        !           245: #define        SVM_EXIT_WRITE_CR0      0x010
        !           246: #define        SVM_EXIT_WRITE_CR3      0x013
        !           247: #define        SVM_EXIT_WRITE_CR4      0x014
        !           248: #define        SVM_EXIT_WRITE_CR8      0x018
        !           249: #define        SVM_EXIT_READ_DR0       0x020
        !           250: #define        SVM_EXIT_READ_DR1       0x021
        !           251: #define        SVM_EXIT_READ_DR2       0x022
        !           252: #define        SVM_EXIT_READ_DR3       0x023
        !           253: #define        SVM_EXIT_READ_DR4       0x024
        !           254: #define        SVM_EXIT_READ_DR5       0x025
        !           255: #define        SVM_EXIT_READ_DR6       0x026
        !           256: #define        SVM_EXIT_READ_DR7       0x027
        !           257: #define        SVM_EXIT_WRITE_DR0      0x030
        !           258: #define        SVM_EXIT_WRITE_DR1      0x031
        !           259: #define        SVM_EXIT_WRITE_DR2      0x032
        !           260: #define        SVM_EXIT_WRITE_DR3      0x033
        !           261: #define        SVM_EXIT_WRITE_DR4      0x034
        !           262: #define        SVM_EXIT_WRITE_DR5      0x035
        !           263: #define        SVM_EXIT_WRITE_DR6      0x036
        !           264: #define        SVM_EXIT_WRITE_DR7      0x037
        !           265: #define SVM_EXIT_EXCP_BASE      0x040
        !           266: #define SVM_EXIT_INTR          0x060
        !           267: #define SVM_EXIT_NMI           0x061
        !           268: #define SVM_EXIT_SMI           0x062
        !           269: #define SVM_EXIT_INIT          0x063
        !           270: #define SVM_EXIT_VINTR         0x064
        !           271: #define SVM_EXIT_CR0_SEL_WRITE 0x065
        !           272: #define SVM_EXIT_IDTR_READ     0x066
        !           273: #define SVM_EXIT_GDTR_READ     0x067
        !           274: #define SVM_EXIT_LDTR_READ     0x068
        !           275: #define SVM_EXIT_TR_READ       0x069
        !           276: #define SVM_EXIT_IDTR_WRITE    0x06a
        !           277: #define SVM_EXIT_GDTR_WRITE    0x06b
        !           278: #define SVM_EXIT_LDTR_WRITE    0x06c
        !           279: #define SVM_EXIT_TR_WRITE      0x06d
        !           280: #define SVM_EXIT_RDTSC         0x06e
        !           281: #define SVM_EXIT_RDPMC         0x06f
        !           282: #define SVM_EXIT_PUSHF         0x070
        !           283: #define SVM_EXIT_POPF          0x071
        !           284: #define SVM_EXIT_CPUID         0x072
        !           285: #define SVM_EXIT_RSM           0x073
        !           286: #define SVM_EXIT_IRET          0x074
        !           287: #define SVM_EXIT_SWINT         0x075
        !           288: #define SVM_EXIT_INVD          0x076
        !           289: #define SVM_EXIT_PAUSE         0x077
        !           290: #define SVM_EXIT_HLT           0x078
        !           291: #define SVM_EXIT_INVLPG                0x079
        !           292: #define SVM_EXIT_INVLPGA       0x07a
        !           293: #define SVM_EXIT_IOIO          0x07b
        !           294: #define SVM_EXIT_MSR           0x07c
        !           295: #define SVM_EXIT_TASK_SWITCH   0x07d
        !           296: #define SVM_EXIT_FERR_FREEZE   0x07e
        !           297: #define SVM_EXIT_SHUTDOWN      0x07f
        !           298: #define SVM_EXIT_VMRUN         0x080
        !           299: #define SVM_EXIT_VMMCALL       0x081
        !           300: #define SVM_EXIT_VMLOAD                0x082
        !           301: #define SVM_EXIT_VMSAVE                0x083
        !           302: #define SVM_EXIT_STGI          0x084
        !           303: #define SVM_EXIT_CLGI          0x085
        !           304: #define SVM_EXIT_SKINIT                0x086
        !           305: #define SVM_EXIT_RDTSCP                0x087
        !           306: #define SVM_EXIT_ICEBP         0x088
        !           307: #define SVM_EXIT_WBINVD                0x089
        !           308: /* only included in documentation, maybe wrong */
        !           309: #define SVM_EXIT_MONITOR       0x08a
        !           310: #define SVM_EXIT_MWAIT         0x08b
        !           311: #define SVM_EXIT_NPF           0x400
        !           312: 
        !           313: #define SVM_EXIT_ERR           -1
        !           314: 
        !           315: #define SVM_CR0_SELECTIVE_MASK (1 << 3 | 1) /* TS and MP */
        !           316: 
        !           317: #define SVM_VMLOAD ".byte 0x0f, 0x01, 0xda"
        !           318: #define SVM_VMRUN  ".byte 0x0f, 0x01, 0xd8"
        !           319: #define SVM_VMSAVE ".byte 0x0f, 0x01, 0xdb"
        !           320: #define SVM_CLGI   ".byte 0x0f, 0x01, 0xdd"
        !           321: #define SVM_STGI   ".byte 0x0f, 0x01, 0xdc"
        !           322: #define SVM_INVLPGA ".byte 0x0f, 0x01, 0xdf"
        !           323: 
        !           324: /* function references */
        !           325: 
        !           326: void helper_stgi();
        !           327: void vmexit(uint64_t exit_code, uint64_t exit_info_1);
        !           328: int svm_check_intercept_param(uint32_t type, uint64_t param);
        !           329: static inline int svm_check_intercept(unsigned int type) {
        !           330:     return svm_check_intercept_param(type, 0);
        !           331: }
        !           332: 
        !           333: 
        !           334: #define INTERCEPTED(mask) (env->intercept & mask)
        !           335: #define INTERCEPTEDw(var, mask) (env->intercept ## var & mask)
        !           336: #define INTERCEPTEDl(var, mask) (env->intercept ## var & mask)
        !           337: 
        !           338: #define SVM_LOAD_SEG(addr, seg_index, seg) \
        !           339:     cpu_x86_load_seg_cache(env, \
        !           340:                     R_##seg_index, \
        !           341:                     lduw_phys(addr + offsetof(struct vmcb, save.seg.selector)),\
        !           342:                     ldq_phys(addr + offsetof(struct vmcb, save.seg.base)),\
        !           343:                     ldl_phys(addr + offsetof(struct vmcb, save.seg.limit)),\
        !           344:                     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))))
        !           345: 
        !           346: #define SVM_LOAD_SEG2(addr, seg_qemu, seg_vmcb) \
        !           347:     env->seg_qemu.selector  = lduw_phys(addr + offsetof(struct vmcb, save.seg_vmcb.selector)); \
        !           348:     env->seg_qemu.base      = ldq_phys(addr + offsetof(struct vmcb, save.seg_vmcb.base)); \
        !           349:     env->seg_qemu.limit     = ldl_phys(addr + offsetof(struct vmcb, save.seg_vmcb.limit)); \
        !           350:     env->seg_qemu.flags     = vmcb2cpu_attrib(lduw_phys(addr + offsetof(struct vmcb, save.seg_vmcb.attrib)), env->seg_qemu.base, env->seg_qemu.limit)
        !           351: 
        !           352: #define SVM_SAVE_SEG(addr, seg_qemu, seg_vmcb) \
        !           353:     stw_phys(addr + offsetof(struct vmcb, save.seg_vmcb.selector), env->seg_qemu.selector); \
        !           354:     stq_phys(addr + offsetof(struct vmcb, save.seg_vmcb.base), env->seg_qemu.base); \
        !           355:     stl_phys(addr + offsetof(struct vmcb, save.seg_vmcb.limit), env->seg_qemu.limit); \
        !           356:     stw_phys(addr + offsetof(struct vmcb, save.seg_vmcb.attrib), cpu2vmcb_attrib(env->seg_qemu.flags))
        !           357: 
        !           358: #endif

unix.superglobalmegacorp.com