1c865f654SCornelia Huck #ifndef X86_SVM_H 2c865f654SCornelia Huck #define X86_SVM_H 37d36db35SAvi Kivity 47d36db35SAvi Kivity #include "libcflat.h" 57d36db35SAvi Kivity 67d36db35SAvi Kivity enum { 77d36db35SAvi Kivity INTERCEPT_INTR, 87d36db35SAvi Kivity INTERCEPT_NMI, 97d36db35SAvi Kivity INTERCEPT_SMI, 107d36db35SAvi Kivity INTERCEPT_INIT, 117d36db35SAvi Kivity INTERCEPT_VINTR, 127d36db35SAvi Kivity INTERCEPT_SELECTIVE_CR0, 137d36db35SAvi Kivity INTERCEPT_STORE_IDTR, 147d36db35SAvi Kivity INTERCEPT_STORE_GDTR, 157d36db35SAvi Kivity INTERCEPT_STORE_LDTR, 167d36db35SAvi Kivity INTERCEPT_STORE_TR, 177d36db35SAvi Kivity INTERCEPT_LOAD_IDTR, 187d36db35SAvi Kivity INTERCEPT_LOAD_GDTR, 197d36db35SAvi Kivity INTERCEPT_LOAD_LDTR, 207d36db35SAvi Kivity INTERCEPT_LOAD_TR, 217d36db35SAvi Kivity INTERCEPT_RDTSC, 227d36db35SAvi Kivity INTERCEPT_RDPMC, 237d36db35SAvi Kivity INTERCEPT_PUSHF, 247d36db35SAvi Kivity INTERCEPT_POPF, 257d36db35SAvi Kivity INTERCEPT_CPUID, 267d36db35SAvi Kivity INTERCEPT_RSM, 277d36db35SAvi Kivity INTERCEPT_IRET, 287d36db35SAvi Kivity INTERCEPT_INTn, 297d36db35SAvi Kivity INTERCEPT_INVD, 307d36db35SAvi Kivity INTERCEPT_PAUSE, 317d36db35SAvi Kivity INTERCEPT_HLT, 327d36db35SAvi Kivity INTERCEPT_INVLPG, 337d36db35SAvi Kivity INTERCEPT_INVLPGA, 347d36db35SAvi Kivity INTERCEPT_IOIO_PROT, 357d36db35SAvi Kivity INTERCEPT_MSR_PROT, 367d36db35SAvi Kivity INTERCEPT_TASK_SWITCH, 377d36db35SAvi Kivity INTERCEPT_FERR_FREEZE, 387d36db35SAvi Kivity INTERCEPT_SHUTDOWN, 397d36db35SAvi Kivity INTERCEPT_VMRUN, 407d36db35SAvi Kivity INTERCEPT_VMMCALL, 417d36db35SAvi Kivity INTERCEPT_VMLOAD, 427d36db35SAvi Kivity INTERCEPT_VMSAVE, 437d36db35SAvi Kivity INTERCEPT_STGI, 447d36db35SAvi Kivity INTERCEPT_CLGI, 457d36db35SAvi Kivity INTERCEPT_SKINIT, 467d36db35SAvi Kivity INTERCEPT_RDTSCP, 477d36db35SAvi Kivity INTERCEPT_ICEBP, 487d36db35SAvi Kivity INTERCEPT_WBINVD, 497d36db35SAvi Kivity INTERCEPT_MONITOR, 507d36db35SAvi Kivity INTERCEPT_MWAIT, 517d36db35SAvi Kivity INTERCEPT_MWAIT_COND, 527d36db35SAvi Kivity }; 537d36db35SAvi Kivity 54f7fa53dcSPaolo Bonzini enum { 55f7fa53dcSPaolo Bonzini VMCB_CLEAN_INTERCEPTS = 1, /* Intercept vectors, TSC offset, pause filter count */ 56f7fa53dcSPaolo Bonzini VMCB_CLEAN_PERM_MAP = 2, /* IOPM Base and MSRPM Base */ 57f7fa53dcSPaolo Bonzini VMCB_CLEAN_ASID = 4, /* ASID */ 58f7fa53dcSPaolo Bonzini VMCB_CLEAN_INTR = 8, /* int_ctl, int_vector */ 59f7fa53dcSPaolo Bonzini VMCB_CLEAN_NPT = 16, /* npt_en, nCR3, gPAT */ 60f7fa53dcSPaolo Bonzini VMCB_CLEAN_CR = 32, /* CR0, CR3, CR4, EFER */ 61f7fa53dcSPaolo Bonzini VMCB_CLEAN_DR = 64, /* DR6, DR7 */ 62f7fa53dcSPaolo Bonzini VMCB_CLEAN_DT = 128, /* GDT, IDT */ 63f7fa53dcSPaolo Bonzini VMCB_CLEAN_SEG = 256, /* CS, DS, SS, ES, CPL */ 64f7fa53dcSPaolo Bonzini VMCB_CLEAN_CR2 = 512, /* CR2 only */ 65f7fa53dcSPaolo Bonzini VMCB_CLEAN_LBR = 1024, /* DBGCTL, BR_FROM, BR_TO, LAST_EX_FROM, LAST_EX_TO */ 66f7fa53dcSPaolo Bonzini VMCB_CLEAN_AVIC = 2048, /* APIC_BAR, APIC_BACKING_PAGE, 67f7fa53dcSPaolo Bonzini PHYSICAL_TABLE pointer, LOGICAL_TABLE pointer */ 68f7fa53dcSPaolo Bonzini VMCB_CLEAN_ALL = 4095, 69f7fa53dcSPaolo Bonzini }; 707d36db35SAvi Kivity 717d36db35SAvi Kivity struct __attribute__ ((__packed__)) vmcb_control_area { 727d36db35SAvi Kivity u16 intercept_cr_read; 737d36db35SAvi Kivity u16 intercept_cr_write; 747d36db35SAvi Kivity u16 intercept_dr_read; 757d36db35SAvi Kivity u16 intercept_dr_write; 767d36db35SAvi Kivity u32 intercept_exceptions; 777d36db35SAvi Kivity u64 intercept; 788650dffeSMaxim Levitsky u8 reserved_1[40]; 798650dffeSMaxim Levitsky u16 pause_filter_thresh; 807d36db35SAvi Kivity u16 pause_filter_count; 817d36db35SAvi Kivity u64 iopm_base_pa; 827d36db35SAvi Kivity u64 msrpm_base_pa; 837d36db35SAvi Kivity u64 tsc_offset; 847d36db35SAvi Kivity u32 asid; 857d36db35SAvi Kivity u8 tlb_ctl; 867d36db35SAvi Kivity u8 reserved_2[3]; 877d36db35SAvi Kivity u32 int_ctl; 887d36db35SAvi Kivity u32 int_vector; 897d36db35SAvi Kivity u32 int_state; 907d36db35SAvi Kivity u8 reserved_3[4]; 917d36db35SAvi Kivity u32 exit_code; 927d36db35SAvi Kivity u32 exit_code_hi; 937d36db35SAvi Kivity u64 exit_info_1; 947d36db35SAvi Kivity u64 exit_info_2; 957d36db35SAvi Kivity u32 exit_int_info; 967d36db35SAvi Kivity u32 exit_int_info_err; 977d36db35SAvi Kivity u64 nested_ctl; 987d36db35SAvi Kivity u8 reserved_4[16]; 997d36db35SAvi Kivity u32 event_inj; 1007d36db35SAvi Kivity u32 event_inj_err; 1017d36db35SAvi Kivity u64 nested_cr3; 102537d39dfSMaxim Levitsky u64 virt_ext; 103f7fa53dcSPaolo Bonzini u32 clean; 104f7fa53dcSPaolo Bonzini u32 reserved_5; 1057d36db35SAvi Kivity u64 next_rip; 106f7fa53dcSPaolo Bonzini u8 insn_len; 107f7fa53dcSPaolo Bonzini u8 insn_bytes[15]; 108f7fa53dcSPaolo Bonzini u8 reserved_6[800]; 1097d36db35SAvi Kivity }; 1107d36db35SAvi Kivity 1117d36db35SAvi Kivity #define TLB_CONTROL_DO_NOTHING 0 1127d36db35SAvi Kivity #define TLB_CONTROL_FLUSH_ALL_ASID 1 1137d36db35SAvi Kivity 1147d36db35SAvi Kivity #define V_TPR_MASK 0x0f 1157d36db35SAvi Kivity 1167d36db35SAvi Kivity #define V_IRQ_SHIFT 8 1177d36db35SAvi Kivity #define V_IRQ_MASK (1 << V_IRQ_SHIFT) 1187d36db35SAvi Kivity 119f6972bd6SLara Lazier #define V_GIF_ENABLED_SHIFT 25 120f6972bd6SLara Lazier #define V_GIF_ENABLED_MASK (1 << V_GIF_ENABLED_SHIFT) 121f6972bd6SLara Lazier 122f6972bd6SLara Lazier #define V_GIF_SHIFT 9 123f6972bd6SLara Lazier #define V_GIF_MASK (1 << V_GIF_SHIFT) 124f6972bd6SLara Lazier 1257d36db35SAvi Kivity #define V_INTR_PRIO_SHIFT 16 1267d36db35SAvi Kivity #define V_INTR_PRIO_MASK (0x0f << V_INTR_PRIO_SHIFT) 1277d36db35SAvi Kivity 1287d36db35SAvi Kivity #define V_IGN_TPR_SHIFT 20 1297d36db35SAvi Kivity #define V_IGN_TPR_MASK (1 << V_IGN_TPR_SHIFT) 1307d36db35SAvi Kivity 1317d36db35SAvi Kivity #define V_INTR_MASKING_SHIFT 24 1327d36db35SAvi Kivity #define V_INTR_MASKING_MASK (1 << V_INTR_MASKING_SHIFT) 1337d36db35SAvi Kivity 1347d36db35SAvi Kivity #define SVM_INTERRUPT_SHADOW_MASK 1 1357d36db35SAvi Kivity 1367d36db35SAvi Kivity #define SVM_IOIO_STR_SHIFT 2 1377d36db35SAvi Kivity #define SVM_IOIO_REP_SHIFT 3 1387d36db35SAvi Kivity #define SVM_IOIO_SIZE_SHIFT 4 1397d36db35SAvi Kivity #define SVM_IOIO_ASIZE_SHIFT 7 1407d36db35SAvi Kivity 1417d36db35SAvi Kivity #define SVM_IOIO_TYPE_MASK 1 1427d36db35SAvi Kivity #define SVM_IOIO_STR_MASK (1 << SVM_IOIO_STR_SHIFT) 1437d36db35SAvi Kivity #define SVM_IOIO_REP_MASK (1 << SVM_IOIO_REP_SHIFT) 1447d36db35SAvi Kivity #define SVM_IOIO_SIZE_MASK (7 << SVM_IOIO_SIZE_SHIFT) 1457d36db35SAvi Kivity #define SVM_IOIO_ASIZE_MASK (7 << SVM_IOIO_ASIZE_SHIFT) 1467d36db35SAvi Kivity 1477d36db35SAvi Kivity #define SVM_VM_CR_VALID_MASK 0x001fULL 1487d36db35SAvi Kivity #define SVM_VM_CR_SVM_LOCK_MASK 0x0008ULL 1497d36db35SAvi Kivity #define SVM_VM_CR_SVM_DIS_MASK 0x0010ULL 1507d36db35SAvi Kivity 151a8503d50SMaxim Levitsky #define TSC_RATIO_DEFAULT 0x0100000000ULL 152a8503d50SMaxim Levitsky 1537d36db35SAvi Kivity struct __attribute__ ((__packed__)) vmcb_seg { 1547d36db35SAvi Kivity u16 selector; 1557d36db35SAvi Kivity u16 attrib; 1567d36db35SAvi Kivity u32 limit; 1577d36db35SAvi Kivity u64 base; 1587d36db35SAvi Kivity }; 1597d36db35SAvi Kivity 1607d36db35SAvi Kivity struct __attribute__ ((__packed__)) vmcb_save_area { 1617d36db35SAvi Kivity struct vmcb_seg es; 1627d36db35SAvi Kivity struct vmcb_seg cs; 1637d36db35SAvi Kivity struct vmcb_seg ss; 1647d36db35SAvi Kivity struct vmcb_seg ds; 1657d36db35SAvi Kivity struct vmcb_seg fs; 1667d36db35SAvi Kivity struct vmcb_seg gs; 1677d36db35SAvi Kivity struct vmcb_seg gdtr; 1687d36db35SAvi Kivity struct vmcb_seg ldtr; 1697d36db35SAvi Kivity struct vmcb_seg idtr; 1707d36db35SAvi Kivity struct vmcb_seg tr; 1717d36db35SAvi Kivity u8 reserved_1[43]; 1727d36db35SAvi Kivity u8 cpl; 1737d36db35SAvi Kivity u8 reserved_2[4]; 1747d36db35SAvi Kivity u64 efer; 1757d36db35SAvi Kivity u8 reserved_3[112]; 1767d36db35SAvi Kivity u64 cr4; 1777d36db35SAvi Kivity u64 cr3; 1787d36db35SAvi Kivity u64 cr0; 1797d36db35SAvi Kivity u64 dr7; 1807d36db35SAvi Kivity u64 dr6; 1817d36db35SAvi Kivity u64 rflags; 1827d36db35SAvi Kivity u64 rip; 1837d36db35SAvi Kivity u8 reserved_4[88]; 1847d36db35SAvi Kivity u64 rsp; 1857d36db35SAvi Kivity u8 reserved_5[24]; 1867d36db35SAvi Kivity u64 rax; 1877d36db35SAvi Kivity u64 star; 1887d36db35SAvi Kivity u64 lstar; 1897d36db35SAvi Kivity u64 cstar; 1907d36db35SAvi Kivity u64 sfmask; 1917d36db35SAvi Kivity u64 kernel_gs_base; 1927d36db35SAvi Kivity u64 sysenter_cs; 1937d36db35SAvi Kivity u64 sysenter_esp; 1947d36db35SAvi Kivity u64 sysenter_eip; 1957d36db35SAvi Kivity u64 cr2; 1967d36db35SAvi Kivity u8 reserved_6[32]; 1977d36db35SAvi Kivity u64 g_pat; 1987d36db35SAvi Kivity u64 dbgctl; 1997d36db35SAvi Kivity u64 br_from; 2007d36db35SAvi Kivity u64 br_to; 2017d36db35SAvi Kivity u64 last_excp_from; 2027d36db35SAvi Kivity u64 last_excp_to; 2037d36db35SAvi Kivity }; 2047d36db35SAvi Kivity 2057d36db35SAvi Kivity struct __attribute__ ((__packed__)) vmcb { 2067d36db35SAvi Kivity struct vmcb_control_area control; 2077d36db35SAvi Kivity struct vmcb_save_area save; 2087d36db35SAvi Kivity }; 2097d36db35SAvi Kivity 2107d36db35SAvi Kivity #define SVM_CPUID_FEATURE_SHIFT 2 2117d36db35SAvi Kivity #define SVM_CPUID_FUNC 0x8000000a 2127d36db35SAvi Kivity 2137d36db35SAvi Kivity #define SVM_VM_CR_SVM_DISABLE 4 2147d36db35SAvi Kivity 2157d36db35SAvi Kivity #define SVM_SELECTOR_S_SHIFT 4 2167d36db35SAvi Kivity #define SVM_SELECTOR_DPL_SHIFT 5 2177d36db35SAvi Kivity #define SVM_SELECTOR_P_SHIFT 7 2187d36db35SAvi Kivity #define SVM_SELECTOR_AVL_SHIFT 8 2197d36db35SAvi Kivity #define SVM_SELECTOR_L_SHIFT 9 2207d36db35SAvi Kivity #define SVM_SELECTOR_DB_SHIFT 10 2217d36db35SAvi Kivity #define SVM_SELECTOR_G_SHIFT 11 2227d36db35SAvi Kivity 2237d36db35SAvi Kivity #define SVM_SELECTOR_TYPE_MASK (0xf) 2247d36db35SAvi Kivity #define SVM_SELECTOR_S_MASK (1 << SVM_SELECTOR_S_SHIFT) 2257d36db35SAvi Kivity #define SVM_SELECTOR_DPL_MASK (3 << SVM_SELECTOR_DPL_SHIFT) 2267d36db35SAvi Kivity #define SVM_SELECTOR_P_MASK (1 << SVM_SELECTOR_P_SHIFT) 2277d36db35SAvi Kivity #define SVM_SELECTOR_AVL_MASK (1 << SVM_SELECTOR_AVL_SHIFT) 2287d36db35SAvi Kivity #define SVM_SELECTOR_L_MASK (1 << SVM_SELECTOR_L_SHIFT) 2297d36db35SAvi Kivity #define SVM_SELECTOR_DB_MASK (1 << SVM_SELECTOR_DB_SHIFT) 2307d36db35SAvi Kivity #define SVM_SELECTOR_G_MASK (1 << SVM_SELECTOR_G_SHIFT) 2317d36db35SAvi Kivity 2327d36db35SAvi Kivity #define SVM_SELECTOR_WRITE_MASK (1 << 1) 2337d36db35SAvi Kivity #define SVM_SELECTOR_READ_MASK SVM_SELECTOR_WRITE_MASK 2347d36db35SAvi Kivity #define SVM_SELECTOR_CODE_MASK (1 << 3) 2357d36db35SAvi Kivity 2367d36db35SAvi Kivity #define INTERCEPT_CR0_MASK 1 2377d36db35SAvi Kivity #define INTERCEPT_CR3_MASK (1 << 3) 2387d36db35SAvi Kivity #define INTERCEPT_CR4_MASK (1 << 4) 2397d36db35SAvi Kivity #define INTERCEPT_CR8_MASK (1 << 8) 2407d36db35SAvi Kivity 2417d36db35SAvi Kivity #define INTERCEPT_DR0_MASK 1 2427d36db35SAvi Kivity #define INTERCEPT_DR1_MASK (1 << 1) 2437d36db35SAvi Kivity #define INTERCEPT_DR2_MASK (1 << 2) 2447d36db35SAvi Kivity #define INTERCEPT_DR3_MASK (1 << 3) 2457d36db35SAvi Kivity #define INTERCEPT_DR4_MASK (1 << 4) 2467d36db35SAvi Kivity #define INTERCEPT_DR5_MASK (1 << 5) 2477d36db35SAvi Kivity #define INTERCEPT_DR6_MASK (1 << 6) 2487d36db35SAvi Kivity #define INTERCEPT_DR7_MASK (1 << 7) 2497d36db35SAvi Kivity 2507d36db35SAvi Kivity #define SVM_EVTINJ_VEC_MASK 0xff 2517d36db35SAvi Kivity 2527d36db35SAvi Kivity #define SVM_EVTINJ_TYPE_SHIFT 8 2537d36db35SAvi Kivity #define SVM_EVTINJ_TYPE_MASK (7 << SVM_EVTINJ_TYPE_SHIFT) 2547d36db35SAvi Kivity 2557d36db35SAvi Kivity #define SVM_EVTINJ_TYPE_INTR (0 << SVM_EVTINJ_TYPE_SHIFT) 2567d36db35SAvi Kivity #define SVM_EVTINJ_TYPE_NMI (2 << SVM_EVTINJ_TYPE_SHIFT) 2577d36db35SAvi Kivity #define SVM_EVTINJ_TYPE_EXEPT (3 << SVM_EVTINJ_TYPE_SHIFT) 2587d36db35SAvi Kivity #define SVM_EVTINJ_TYPE_SOFT (4 << SVM_EVTINJ_TYPE_SHIFT) 2597d36db35SAvi Kivity 2607d36db35SAvi Kivity #define SVM_EVTINJ_VALID (1 << 31) 2617d36db35SAvi Kivity #define SVM_EVTINJ_VALID_ERR (1 << 11) 2627d36db35SAvi Kivity 2637d36db35SAvi Kivity #define SVM_EXITINTINFO_VEC_MASK SVM_EVTINJ_VEC_MASK 2647d36db35SAvi Kivity #define SVM_EXITINTINFO_TYPE_MASK SVM_EVTINJ_TYPE_MASK 2657d36db35SAvi Kivity 2667d36db35SAvi Kivity #define SVM_EXITINTINFO_TYPE_INTR SVM_EVTINJ_TYPE_INTR 2677d36db35SAvi Kivity #define SVM_EXITINTINFO_TYPE_NMI SVM_EVTINJ_TYPE_NMI 2687d36db35SAvi Kivity #define SVM_EXITINTINFO_TYPE_EXEPT SVM_EVTINJ_TYPE_EXEPT 2697d36db35SAvi Kivity #define SVM_EXITINTINFO_TYPE_SOFT SVM_EVTINJ_TYPE_SOFT 2707d36db35SAvi Kivity 2717d36db35SAvi Kivity #define SVM_EXITINTINFO_VALID SVM_EVTINJ_VALID 2727d36db35SAvi Kivity #define SVM_EXITINTINFO_VALID_ERR SVM_EVTINJ_VALID_ERR 2737d36db35SAvi Kivity 2747d36db35SAvi Kivity #define SVM_EXITINFOSHIFT_TS_REASON_IRET 36 2757d36db35SAvi Kivity #define SVM_EXITINFOSHIFT_TS_REASON_JMP 38 2767d36db35SAvi Kivity #define SVM_EXITINFOSHIFT_TS_HAS_ERROR_CODE 44 2777d36db35SAvi Kivity 2787d36db35SAvi Kivity #define SVM_EXIT_READ_CR0 0x000 2797d36db35SAvi Kivity #define SVM_EXIT_READ_CR3 0x003 2807d36db35SAvi Kivity #define SVM_EXIT_READ_CR4 0x004 2817d36db35SAvi Kivity #define SVM_EXIT_READ_CR8 0x008 2827d36db35SAvi Kivity #define SVM_EXIT_WRITE_CR0 0x010 2837d36db35SAvi Kivity #define SVM_EXIT_WRITE_CR3 0x013 2847d36db35SAvi Kivity #define SVM_EXIT_WRITE_CR4 0x014 2857d36db35SAvi Kivity #define SVM_EXIT_WRITE_CR8 0x018 2867d36db35SAvi Kivity #define SVM_EXIT_READ_DR0 0x020 2877d36db35SAvi Kivity #define SVM_EXIT_READ_DR1 0x021 2887d36db35SAvi Kivity #define SVM_EXIT_READ_DR2 0x022 2897d36db35SAvi Kivity #define SVM_EXIT_READ_DR3 0x023 2907d36db35SAvi Kivity #define SVM_EXIT_READ_DR4 0x024 2917d36db35SAvi Kivity #define SVM_EXIT_READ_DR5 0x025 2927d36db35SAvi Kivity #define SVM_EXIT_READ_DR6 0x026 2937d36db35SAvi Kivity #define SVM_EXIT_READ_DR7 0x027 2947d36db35SAvi Kivity #define SVM_EXIT_WRITE_DR0 0x030 2957d36db35SAvi Kivity #define SVM_EXIT_WRITE_DR1 0x031 2967d36db35SAvi Kivity #define SVM_EXIT_WRITE_DR2 0x032 2977d36db35SAvi Kivity #define SVM_EXIT_WRITE_DR3 0x033 2987d36db35SAvi Kivity #define SVM_EXIT_WRITE_DR4 0x034 2997d36db35SAvi Kivity #define SVM_EXIT_WRITE_DR5 0x035 3007d36db35SAvi Kivity #define SVM_EXIT_WRITE_DR6 0x036 3017d36db35SAvi Kivity #define SVM_EXIT_WRITE_DR7 0x037 3027d36db35SAvi Kivity #define SVM_EXIT_EXCP_BASE 0x040 3037d36db35SAvi Kivity #define SVM_EXIT_INTR 0x060 3047d36db35SAvi Kivity #define SVM_EXIT_NMI 0x061 3057d36db35SAvi Kivity #define SVM_EXIT_SMI 0x062 3067d36db35SAvi Kivity #define SVM_EXIT_INIT 0x063 3077d36db35SAvi Kivity #define SVM_EXIT_VINTR 0x064 3087d36db35SAvi Kivity #define SVM_EXIT_CR0_SEL_WRITE 0x065 3097d36db35SAvi Kivity #define SVM_EXIT_IDTR_READ 0x066 3107d36db35SAvi Kivity #define SVM_EXIT_GDTR_READ 0x067 3117d36db35SAvi Kivity #define SVM_EXIT_LDTR_READ 0x068 3127d36db35SAvi Kivity #define SVM_EXIT_TR_READ 0x069 3137d36db35SAvi Kivity #define SVM_EXIT_IDTR_WRITE 0x06a 3147d36db35SAvi Kivity #define SVM_EXIT_GDTR_WRITE 0x06b 3157d36db35SAvi Kivity #define SVM_EXIT_LDTR_WRITE 0x06c 3167d36db35SAvi Kivity #define SVM_EXIT_TR_WRITE 0x06d 3177d36db35SAvi Kivity #define SVM_EXIT_RDTSC 0x06e 3187d36db35SAvi Kivity #define SVM_EXIT_RDPMC 0x06f 3197d36db35SAvi Kivity #define SVM_EXIT_PUSHF 0x070 3207d36db35SAvi Kivity #define SVM_EXIT_POPF 0x071 3217d36db35SAvi Kivity #define SVM_EXIT_CPUID 0x072 3227d36db35SAvi Kivity #define SVM_EXIT_RSM 0x073 3237d36db35SAvi Kivity #define SVM_EXIT_IRET 0x074 3247d36db35SAvi Kivity #define SVM_EXIT_SWINT 0x075 3257d36db35SAvi Kivity #define SVM_EXIT_INVD 0x076 3267d36db35SAvi Kivity #define SVM_EXIT_PAUSE 0x077 3277d36db35SAvi Kivity #define SVM_EXIT_HLT 0x078 3287d36db35SAvi Kivity #define SVM_EXIT_INVLPG 0x079 3297d36db35SAvi Kivity #define SVM_EXIT_INVLPGA 0x07a 3307d36db35SAvi Kivity #define SVM_EXIT_IOIO 0x07b 3317d36db35SAvi Kivity #define SVM_EXIT_MSR 0x07c 3327d36db35SAvi Kivity #define SVM_EXIT_TASK_SWITCH 0x07d 3337d36db35SAvi Kivity #define SVM_EXIT_FERR_FREEZE 0x07e 3347d36db35SAvi Kivity #define SVM_EXIT_SHUTDOWN 0x07f 3357d36db35SAvi Kivity #define SVM_EXIT_VMRUN 0x080 3367d36db35SAvi Kivity #define SVM_EXIT_VMMCALL 0x081 3377d36db35SAvi Kivity #define SVM_EXIT_VMLOAD 0x082 3387d36db35SAvi Kivity #define SVM_EXIT_VMSAVE 0x083 3397d36db35SAvi Kivity #define SVM_EXIT_STGI 0x084 3407d36db35SAvi Kivity #define SVM_EXIT_CLGI 0x085 3417d36db35SAvi Kivity #define SVM_EXIT_SKINIT 0x086 3427d36db35SAvi Kivity #define SVM_EXIT_RDTSCP 0x087 3437d36db35SAvi Kivity #define SVM_EXIT_ICEBP 0x088 3447d36db35SAvi Kivity #define SVM_EXIT_WBINVD 0x089 3457d36db35SAvi Kivity #define SVM_EXIT_MONITOR 0x08a 3467d36db35SAvi Kivity #define SVM_EXIT_MWAIT 0x08b 3477d36db35SAvi Kivity #define SVM_EXIT_MWAIT_COND 0x08c 3487d36db35SAvi Kivity #define SVM_EXIT_NPF 0x400 3497d36db35SAvi Kivity 3507d36db35SAvi Kivity #define SVM_EXIT_ERR -1 3517d36db35SAvi Kivity 3527d36db35SAvi Kivity #define SVM_CR0_SELECTIVE_MASK (X86_CR0_TS | X86_CR0_MP) 3537d36db35SAvi Kivity 354eae10e8fSKrish Sadhukhan #define SVM_CR0_RESERVED_MASK 0xffffffff00000000U 3556d0ecbf6SKrish Sadhukhan #define SVM_CR3_LONG_MBZ_MASK 0xfff0000000000000U 3566d0ecbf6SKrish Sadhukhan #define SVM_CR3_LONG_RESERVED_MASK 0x0000000000000fe7U 3576d0ecbf6SKrish Sadhukhan #define SVM_CR3_PAE_LEGACY_RESERVED_MASK 0x0000000000000007U 358d30973c3SWei Huang #define SVM_CR4_LEGACY_RESERVED_MASK 0xff08e000U 359d30973c3SWei Huang #define SVM_CR4_RESERVED_MASK 0xffffffffff08e000U 360eae10e8fSKrish Sadhukhan #define SVM_DR6_RESERVED_MASK 0xffffffffffff1ff0U 361eae10e8fSKrish Sadhukhan #define SVM_DR7_RESERVED_MASK 0xffffffff0000cc00U 362eae10e8fSKrish Sadhukhan #define SVM_EFER_RESERVED_MASK 0xffffffffffff0200U 363eae10e8fSKrish Sadhukhan 364ad879127SKrish Sadhukhan #define MSR_BITMAP_SIZE 8192 3657d36db35SAvi Kivity 366537d39dfSMaxim Levitsky #define LBR_CTL_ENABLE_MASK BIT_ULL(0) 367537d39dfSMaxim Levitsky 368ad879127SKrish Sadhukhan struct svm_test { 369ad879127SKrish Sadhukhan const char *name; 370ad879127SKrish Sadhukhan bool (*supported)(void); 371ad879127SKrish Sadhukhan void (*prepare)(struct svm_test *test); 372ad879127SKrish Sadhukhan void (*prepare_gif_clear)(struct svm_test *test); 373ad879127SKrish Sadhukhan void (*guest_func)(struct svm_test *test); 374ad879127SKrish Sadhukhan bool (*finished)(struct svm_test *test); 375ad879127SKrish Sadhukhan bool (*succeeded)(struct svm_test *test); 376ad879127SKrish Sadhukhan int exits; 377ad879127SKrish Sadhukhan ulong scratch; 3788660d1b5SKrish Sadhukhan /* Alternative test interface. */ 3798660d1b5SKrish Sadhukhan void (*v2)(void); 38048f67910SCathy Avery int on_vcpu; 38148f67910SCathy Avery bool on_vcpu_done; 382ad879127SKrish Sadhukhan }; 383ad879127SKrish Sadhukhan 384ad879127SKrish Sadhukhan struct regs { 385ad879127SKrish Sadhukhan u64 rax; 386ad879127SKrish Sadhukhan u64 rbx; 387ad879127SKrish Sadhukhan u64 rcx; 388ad879127SKrish Sadhukhan u64 rdx; 389ad879127SKrish Sadhukhan u64 cr2; 390ad879127SKrish Sadhukhan u64 rbp; 391ad879127SKrish Sadhukhan u64 rsi; 392ad879127SKrish Sadhukhan u64 rdi; 393ad879127SKrish Sadhukhan u64 r8; 394ad879127SKrish Sadhukhan u64 r9; 395ad879127SKrish Sadhukhan u64 r10; 396ad879127SKrish Sadhukhan u64 r11; 397ad879127SKrish Sadhukhan u64 r12; 398ad879127SKrish Sadhukhan u64 r13; 399ad879127SKrish Sadhukhan u64 r14; 400ad879127SKrish Sadhukhan u64 r15; 401ad879127SKrish Sadhukhan u64 rflags; 402ad879127SKrish Sadhukhan }; 403ad879127SKrish Sadhukhan 4048660d1b5SKrish Sadhukhan typedef void (*test_guest_func)(struct svm_test *); 4058660d1b5SKrish Sadhukhan 406712840d5SManali Shukla int run_svm_tests(int ac, char **av, struct svm_test *svm_tests); 407ad879127SKrish Sadhukhan u64 *npt_get_pte(u64 address); 408ad879127SKrish Sadhukhan u64 *npt_get_pde(u64 address); 409*6f5ce7c1SManali Shukla u64 *npt_get_pdpe(u64 address); 410c6405e37SNadav Amit u64 *npt_get_pml4e(void); 411ad879127SKrish Sadhukhan bool smp_supported(void); 412ad879127SKrish Sadhukhan bool default_supported(void); 413f6972bd6SLara Lazier bool vgif_supported(void); 414537d39dfSMaxim Levitsky bool lbrv_supported(void); 415a8503d50SMaxim Levitsky bool tsc_scale_supported(void); 4168650dffeSMaxim Levitsky bool pause_filter_supported(void); 4178650dffeSMaxim Levitsky bool pause_threshold_supported(void); 418ad879127SKrish Sadhukhan void default_prepare(struct svm_test *test); 419ad879127SKrish Sadhukhan void default_prepare_gif_clear(struct svm_test *test); 420ad879127SKrish Sadhukhan bool default_finished(struct svm_test *test); 421ad879127SKrish Sadhukhan bool npt_supported(void); 422ad879127SKrish Sadhukhan int get_test_stage(struct svm_test *test); 423ad879127SKrish Sadhukhan void set_test_stage(struct svm_test *test, int s); 424ad879127SKrish Sadhukhan void inc_test_stage(struct svm_test *test); 425ad879127SKrish Sadhukhan void vmcb_ident(struct vmcb *vmcb); 426ad879127SKrish Sadhukhan struct regs get_regs(void); 427ad879127SKrish Sadhukhan void vmmcall(void); 428a6495564SKrish Sadhukhan int __svm_vmrun(u64 rip); 429ea9bf4adSMaxim Levitsky void __svm_bare_vmrun(void); 4308660d1b5SKrish Sadhukhan int svm_vmrun(void); 4318660d1b5SKrish Sadhukhan void test_set_guest(test_guest_func func); 432*6f5ce7c1SManali Shukla u64* get_npt_pte(u64 *pml4, u64 guest_addr, int level); 433ad879127SKrish Sadhukhan 434096cf7feSPaolo Bonzini extern struct vmcb *vmcb; 435096cf7feSPaolo Bonzini 436c45bccfcSMaxim Levitsky static inline void stgi(void) 437c45bccfcSMaxim Levitsky { 438c45bccfcSMaxim Levitsky asm volatile ("stgi"); 439c45bccfcSMaxim Levitsky } 440c45bccfcSMaxim Levitsky 441c45bccfcSMaxim Levitsky static inline void clgi(void) 442c45bccfcSMaxim Levitsky { 443c45bccfcSMaxim Levitsky asm volatile ("clgi"); 444c45bccfcSMaxim Levitsky } 445c45bccfcSMaxim Levitsky 446c45bccfcSMaxim Levitsky 447ea9bf4adSMaxim Levitsky 448ea9bf4adSMaxim Levitsky #define SAVE_GPR_C \ 449ea9bf4adSMaxim Levitsky "xchg %%rbx, regs+0x8\n\t" \ 450ea9bf4adSMaxim Levitsky "xchg %%rcx, regs+0x10\n\t" \ 451ea9bf4adSMaxim Levitsky "xchg %%rdx, regs+0x18\n\t" \ 452ea9bf4adSMaxim Levitsky "xchg %%rbp, regs+0x28\n\t" \ 453ea9bf4adSMaxim Levitsky "xchg %%rsi, regs+0x30\n\t" \ 454ea9bf4adSMaxim Levitsky "xchg %%rdi, regs+0x38\n\t" \ 455ea9bf4adSMaxim Levitsky "xchg %%r8, regs+0x40\n\t" \ 456ea9bf4adSMaxim Levitsky "xchg %%r9, regs+0x48\n\t" \ 457ea9bf4adSMaxim Levitsky "xchg %%r10, regs+0x50\n\t" \ 458ea9bf4adSMaxim Levitsky "xchg %%r11, regs+0x58\n\t" \ 459ea9bf4adSMaxim Levitsky "xchg %%r12, regs+0x60\n\t" \ 460ea9bf4adSMaxim Levitsky "xchg %%r13, regs+0x68\n\t" \ 461ea9bf4adSMaxim Levitsky "xchg %%r14, regs+0x70\n\t" \ 462ea9bf4adSMaxim Levitsky "xchg %%r15, regs+0x78\n\t" 463ea9bf4adSMaxim Levitsky 464ea9bf4adSMaxim Levitsky #define LOAD_GPR_C SAVE_GPR_C 465ea9bf4adSMaxim Levitsky 466ea9bf4adSMaxim Levitsky #define ASM_PRE_VMRUN_CMD \ 467ea9bf4adSMaxim Levitsky "vmload %%rax\n\t" \ 468ea9bf4adSMaxim Levitsky "mov regs+0x80, %%r15\n\t" \ 469ea9bf4adSMaxim Levitsky "mov %%r15, 0x170(%%rax)\n\t" \ 470ea9bf4adSMaxim Levitsky "mov regs, %%r15\n\t" \ 471ea9bf4adSMaxim Levitsky "mov %%r15, 0x1f8(%%rax)\n\t" \ 472ea9bf4adSMaxim Levitsky LOAD_GPR_C \ 473ea9bf4adSMaxim Levitsky 474ea9bf4adSMaxim Levitsky #define ASM_POST_VMRUN_CMD \ 475ea9bf4adSMaxim Levitsky SAVE_GPR_C \ 476ea9bf4adSMaxim Levitsky "mov 0x170(%%rax), %%r15\n\t" \ 477ea9bf4adSMaxim Levitsky "mov %%r15, regs+0x80\n\t" \ 478ea9bf4adSMaxim Levitsky "mov 0x1f8(%%rax), %%r15\n\t" \ 479ea9bf4adSMaxim Levitsky "mov %%r15, regs\n\t" \ 480ea9bf4adSMaxim Levitsky "vmsave %%rax\n\t" \ 481ea9bf4adSMaxim Levitsky 482ea9bf4adSMaxim Levitsky 483ea9bf4adSMaxim Levitsky 484ea9bf4adSMaxim Levitsky #define SVM_BARE_VMRUN \ 485ea9bf4adSMaxim Levitsky asm volatile ( \ 486ea9bf4adSMaxim Levitsky ASM_PRE_VMRUN_CMD \ 487ea9bf4adSMaxim Levitsky "vmrun %%rax\n\t" \ 488ea9bf4adSMaxim Levitsky ASM_POST_VMRUN_CMD \ 489ea9bf4adSMaxim Levitsky : \ 490ea9bf4adSMaxim Levitsky : "a" (virt_to_phys(vmcb)) \ 491ea9bf4adSMaxim Levitsky : "memory", "r15") \ 492ea9bf4adSMaxim Levitsky 493ad879127SKrish Sadhukhan #endif 494