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; 787d36db35SAvi Kivity u8 reserved_1[42]; 797d36db35SAvi Kivity u16 pause_filter_count; 807d36db35SAvi Kivity u64 iopm_base_pa; 817d36db35SAvi Kivity u64 msrpm_base_pa; 827d36db35SAvi Kivity u64 tsc_offset; 837d36db35SAvi Kivity u32 asid; 847d36db35SAvi Kivity u8 tlb_ctl; 857d36db35SAvi Kivity u8 reserved_2[3]; 867d36db35SAvi Kivity u32 int_ctl; 877d36db35SAvi Kivity u32 int_vector; 887d36db35SAvi Kivity u32 int_state; 897d36db35SAvi Kivity u8 reserved_3[4]; 907d36db35SAvi Kivity u32 exit_code; 917d36db35SAvi Kivity u32 exit_code_hi; 927d36db35SAvi Kivity u64 exit_info_1; 937d36db35SAvi Kivity u64 exit_info_2; 947d36db35SAvi Kivity u32 exit_int_info; 957d36db35SAvi Kivity u32 exit_int_info_err; 967d36db35SAvi Kivity u64 nested_ctl; 977d36db35SAvi Kivity u8 reserved_4[16]; 987d36db35SAvi Kivity u32 event_inj; 997d36db35SAvi Kivity u32 event_inj_err; 1007d36db35SAvi Kivity u64 nested_cr3; 101537d39dfSMaxim Levitsky u64 virt_ext; 102f7fa53dcSPaolo Bonzini u32 clean; 103f7fa53dcSPaolo Bonzini u32 reserved_5; 1047d36db35SAvi Kivity u64 next_rip; 105f7fa53dcSPaolo Bonzini u8 insn_len; 106f7fa53dcSPaolo Bonzini u8 insn_bytes[15]; 107f7fa53dcSPaolo Bonzini u8 reserved_6[800]; 1087d36db35SAvi Kivity }; 1097d36db35SAvi Kivity 1107d36db35SAvi Kivity #define TLB_CONTROL_DO_NOTHING 0 1117d36db35SAvi Kivity #define TLB_CONTROL_FLUSH_ALL_ASID 1 1127d36db35SAvi Kivity 1137d36db35SAvi Kivity #define V_TPR_MASK 0x0f 1147d36db35SAvi Kivity 1157d36db35SAvi Kivity #define V_IRQ_SHIFT 8 1167d36db35SAvi Kivity #define V_IRQ_MASK (1 << V_IRQ_SHIFT) 1177d36db35SAvi Kivity 118f6972bd6SLara Lazier #define V_GIF_ENABLED_SHIFT 25 119f6972bd6SLara Lazier #define V_GIF_ENABLED_MASK (1 << V_GIF_ENABLED_SHIFT) 120f6972bd6SLara Lazier 121f6972bd6SLara Lazier #define V_GIF_SHIFT 9 122f6972bd6SLara Lazier #define V_GIF_MASK (1 << V_GIF_SHIFT) 123f6972bd6SLara Lazier 1247d36db35SAvi Kivity #define V_INTR_PRIO_SHIFT 16 1257d36db35SAvi Kivity #define V_INTR_PRIO_MASK (0x0f << V_INTR_PRIO_SHIFT) 1267d36db35SAvi Kivity 1277d36db35SAvi Kivity #define V_IGN_TPR_SHIFT 20 1287d36db35SAvi Kivity #define V_IGN_TPR_MASK (1 << V_IGN_TPR_SHIFT) 1297d36db35SAvi Kivity 1307d36db35SAvi Kivity #define V_INTR_MASKING_SHIFT 24 1317d36db35SAvi Kivity #define V_INTR_MASKING_MASK (1 << V_INTR_MASKING_SHIFT) 1327d36db35SAvi Kivity 1337d36db35SAvi Kivity #define SVM_INTERRUPT_SHADOW_MASK 1 1347d36db35SAvi Kivity 1357d36db35SAvi Kivity #define SVM_IOIO_STR_SHIFT 2 1367d36db35SAvi Kivity #define SVM_IOIO_REP_SHIFT 3 1377d36db35SAvi Kivity #define SVM_IOIO_SIZE_SHIFT 4 1387d36db35SAvi Kivity #define SVM_IOIO_ASIZE_SHIFT 7 1397d36db35SAvi Kivity 1407d36db35SAvi Kivity #define SVM_IOIO_TYPE_MASK 1 1417d36db35SAvi Kivity #define SVM_IOIO_STR_MASK (1 << SVM_IOIO_STR_SHIFT) 1427d36db35SAvi Kivity #define SVM_IOIO_REP_MASK (1 << SVM_IOIO_REP_SHIFT) 1437d36db35SAvi Kivity #define SVM_IOIO_SIZE_MASK (7 << SVM_IOIO_SIZE_SHIFT) 1447d36db35SAvi Kivity #define SVM_IOIO_ASIZE_MASK (7 << SVM_IOIO_ASIZE_SHIFT) 1457d36db35SAvi Kivity 1467d36db35SAvi Kivity #define SVM_VM_CR_VALID_MASK 0x001fULL 1477d36db35SAvi Kivity #define SVM_VM_CR_SVM_LOCK_MASK 0x0008ULL 1487d36db35SAvi Kivity #define SVM_VM_CR_SVM_DIS_MASK 0x0010ULL 1497d36db35SAvi Kivity 1507d36db35SAvi Kivity struct __attribute__ ((__packed__)) vmcb_seg { 1517d36db35SAvi Kivity u16 selector; 1527d36db35SAvi Kivity u16 attrib; 1537d36db35SAvi Kivity u32 limit; 1547d36db35SAvi Kivity u64 base; 1557d36db35SAvi Kivity }; 1567d36db35SAvi Kivity 1577d36db35SAvi Kivity struct __attribute__ ((__packed__)) vmcb_save_area { 1587d36db35SAvi Kivity struct vmcb_seg es; 1597d36db35SAvi Kivity struct vmcb_seg cs; 1607d36db35SAvi Kivity struct vmcb_seg ss; 1617d36db35SAvi Kivity struct vmcb_seg ds; 1627d36db35SAvi Kivity struct vmcb_seg fs; 1637d36db35SAvi Kivity struct vmcb_seg gs; 1647d36db35SAvi Kivity struct vmcb_seg gdtr; 1657d36db35SAvi Kivity struct vmcb_seg ldtr; 1667d36db35SAvi Kivity struct vmcb_seg idtr; 1677d36db35SAvi Kivity struct vmcb_seg tr; 1687d36db35SAvi Kivity u8 reserved_1[43]; 1697d36db35SAvi Kivity u8 cpl; 1707d36db35SAvi Kivity u8 reserved_2[4]; 1717d36db35SAvi Kivity u64 efer; 1727d36db35SAvi Kivity u8 reserved_3[112]; 1737d36db35SAvi Kivity u64 cr4; 1747d36db35SAvi Kivity u64 cr3; 1757d36db35SAvi Kivity u64 cr0; 1767d36db35SAvi Kivity u64 dr7; 1777d36db35SAvi Kivity u64 dr6; 1787d36db35SAvi Kivity u64 rflags; 1797d36db35SAvi Kivity u64 rip; 1807d36db35SAvi Kivity u8 reserved_4[88]; 1817d36db35SAvi Kivity u64 rsp; 1827d36db35SAvi Kivity u8 reserved_5[24]; 1837d36db35SAvi Kivity u64 rax; 1847d36db35SAvi Kivity u64 star; 1857d36db35SAvi Kivity u64 lstar; 1867d36db35SAvi Kivity u64 cstar; 1877d36db35SAvi Kivity u64 sfmask; 1887d36db35SAvi Kivity u64 kernel_gs_base; 1897d36db35SAvi Kivity u64 sysenter_cs; 1907d36db35SAvi Kivity u64 sysenter_esp; 1917d36db35SAvi Kivity u64 sysenter_eip; 1927d36db35SAvi Kivity u64 cr2; 1937d36db35SAvi Kivity u8 reserved_6[32]; 1947d36db35SAvi Kivity u64 g_pat; 1957d36db35SAvi Kivity u64 dbgctl; 1967d36db35SAvi Kivity u64 br_from; 1977d36db35SAvi Kivity u64 br_to; 1987d36db35SAvi Kivity u64 last_excp_from; 1997d36db35SAvi Kivity u64 last_excp_to; 2007d36db35SAvi Kivity }; 2017d36db35SAvi Kivity 2027d36db35SAvi Kivity struct __attribute__ ((__packed__)) vmcb { 2037d36db35SAvi Kivity struct vmcb_control_area control; 2047d36db35SAvi Kivity struct vmcb_save_area save; 2057d36db35SAvi Kivity }; 2067d36db35SAvi Kivity 2077d36db35SAvi Kivity #define SVM_CPUID_FEATURE_SHIFT 2 2087d36db35SAvi Kivity #define SVM_CPUID_FUNC 0x8000000a 2097d36db35SAvi Kivity 2107d36db35SAvi Kivity #define SVM_VM_CR_SVM_DISABLE 4 2117d36db35SAvi Kivity 2127d36db35SAvi Kivity #define SVM_SELECTOR_S_SHIFT 4 2137d36db35SAvi Kivity #define SVM_SELECTOR_DPL_SHIFT 5 2147d36db35SAvi Kivity #define SVM_SELECTOR_P_SHIFT 7 2157d36db35SAvi Kivity #define SVM_SELECTOR_AVL_SHIFT 8 2167d36db35SAvi Kivity #define SVM_SELECTOR_L_SHIFT 9 2177d36db35SAvi Kivity #define SVM_SELECTOR_DB_SHIFT 10 2187d36db35SAvi Kivity #define SVM_SELECTOR_G_SHIFT 11 2197d36db35SAvi Kivity 2207d36db35SAvi Kivity #define SVM_SELECTOR_TYPE_MASK (0xf) 2217d36db35SAvi Kivity #define SVM_SELECTOR_S_MASK (1 << SVM_SELECTOR_S_SHIFT) 2227d36db35SAvi Kivity #define SVM_SELECTOR_DPL_MASK (3 << SVM_SELECTOR_DPL_SHIFT) 2237d36db35SAvi Kivity #define SVM_SELECTOR_P_MASK (1 << SVM_SELECTOR_P_SHIFT) 2247d36db35SAvi Kivity #define SVM_SELECTOR_AVL_MASK (1 << SVM_SELECTOR_AVL_SHIFT) 2257d36db35SAvi Kivity #define SVM_SELECTOR_L_MASK (1 << SVM_SELECTOR_L_SHIFT) 2267d36db35SAvi Kivity #define SVM_SELECTOR_DB_MASK (1 << SVM_SELECTOR_DB_SHIFT) 2277d36db35SAvi Kivity #define SVM_SELECTOR_G_MASK (1 << SVM_SELECTOR_G_SHIFT) 2287d36db35SAvi Kivity 2297d36db35SAvi Kivity #define SVM_SELECTOR_WRITE_MASK (1 << 1) 2307d36db35SAvi Kivity #define SVM_SELECTOR_READ_MASK SVM_SELECTOR_WRITE_MASK 2317d36db35SAvi Kivity #define SVM_SELECTOR_CODE_MASK (1 << 3) 2327d36db35SAvi Kivity 2337d36db35SAvi Kivity #define INTERCEPT_CR0_MASK 1 2347d36db35SAvi Kivity #define INTERCEPT_CR3_MASK (1 << 3) 2357d36db35SAvi Kivity #define INTERCEPT_CR4_MASK (1 << 4) 2367d36db35SAvi Kivity #define INTERCEPT_CR8_MASK (1 << 8) 2377d36db35SAvi Kivity 2387d36db35SAvi Kivity #define INTERCEPT_DR0_MASK 1 2397d36db35SAvi Kivity #define INTERCEPT_DR1_MASK (1 << 1) 2407d36db35SAvi Kivity #define INTERCEPT_DR2_MASK (1 << 2) 2417d36db35SAvi Kivity #define INTERCEPT_DR3_MASK (1 << 3) 2427d36db35SAvi Kivity #define INTERCEPT_DR4_MASK (1 << 4) 2437d36db35SAvi Kivity #define INTERCEPT_DR5_MASK (1 << 5) 2447d36db35SAvi Kivity #define INTERCEPT_DR6_MASK (1 << 6) 2457d36db35SAvi Kivity #define INTERCEPT_DR7_MASK (1 << 7) 2467d36db35SAvi Kivity 2477d36db35SAvi Kivity #define SVM_EVTINJ_VEC_MASK 0xff 2487d36db35SAvi Kivity 2497d36db35SAvi Kivity #define SVM_EVTINJ_TYPE_SHIFT 8 2507d36db35SAvi Kivity #define SVM_EVTINJ_TYPE_MASK (7 << SVM_EVTINJ_TYPE_SHIFT) 2517d36db35SAvi Kivity 2527d36db35SAvi Kivity #define SVM_EVTINJ_TYPE_INTR (0 << SVM_EVTINJ_TYPE_SHIFT) 2537d36db35SAvi Kivity #define SVM_EVTINJ_TYPE_NMI (2 << SVM_EVTINJ_TYPE_SHIFT) 2547d36db35SAvi Kivity #define SVM_EVTINJ_TYPE_EXEPT (3 << SVM_EVTINJ_TYPE_SHIFT) 2557d36db35SAvi Kivity #define SVM_EVTINJ_TYPE_SOFT (4 << SVM_EVTINJ_TYPE_SHIFT) 2567d36db35SAvi Kivity 2577d36db35SAvi Kivity #define SVM_EVTINJ_VALID (1 << 31) 2587d36db35SAvi Kivity #define SVM_EVTINJ_VALID_ERR (1 << 11) 2597d36db35SAvi Kivity 2607d36db35SAvi Kivity #define SVM_EXITINTINFO_VEC_MASK SVM_EVTINJ_VEC_MASK 2617d36db35SAvi Kivity #define SVM_EXITINTINFO_TYPE_MASK SVM_EVTINJ_TYPE_MASK 2627d36db35SAvi Kivity 2637d36db35SAvi Kivity #define SVM_EXITINTINFO_TYPE_INTR SVM_EVTINJ_TYPE_INTR 2647d36db35SAvi Kivity #define SVM_EXITINTINFO_TYPE_NMI SVM_EVTINJ_TYPE_NMI 2657d36db35SAvi Kivity #define SVM_EXITINTINFO_TYPE_EXEPT SVM_EVTINJ_TYPE_EXEPT 2667d36db35SAvi Kivity #define SVM_EXITINTINFO_TYPE_SOFT SVM_EVTINJ_TYPE_SOFT 2677d36db35SAvi Kivity 2687d36db35SAvi Kivity #define SVM_EXITINTINFO_VALID SVM_EVTINJ_VALID 2697d36db35SAvi Kivity #define SVM_EXITINTINFO_VALID_ERR SVM_EVTINJ_VALID_ERR 2707d36db35SAvi Kivity 2717d36db35SAvi Kivity #define SVM_EXITINFOSHIFT_TS_REASON_IRET 36 2727d36db35SAvi Kivity #define SVM_EXITINFOSHIFT_TS_REASON_JMP 38 2737d36db35SAvi Kivity #define SVM_EXITINFOSHIFT_TS_HAS_ERROR_CODE 44 2747d36db35SAvi Kivity 2757d36db35SAvi Kivity #define SVM_EXIT_READ_CR0 0x000 2767d36db35SAvi Kivity #define SVM_EXIT_READ_CR3 0x003 2777d36db35SAvi Kivity #define SVM_EXIT_READ_CR4 0x004 2787d36db35SAvi Kivity #define SVM_EXIT_READ_CR8 0x008 2797d36db35SAvi Kivity #define SVM_EXIT_WRITE_CR0 0x010 2807d36db35SAvi Kivity #define SVM_EXIT_WRITE_CR3 0x013 2817d36db35SAvi Kivity #define SVM_EXIT_WRITE_CR4 0x014 2827d36db35SAvi Kivity #define SVM_EXIT_WRITE_CR8 0x018 2837d36db35SAvi Kivity #define SVM_EXIT_READ_DR0 0x020 2847d36db35SAvi Kivity #define SVM_EXIT_READ_DR1 0x021 2857d36db35SAvi Kivity #define SVM_EXIT_READ_DR2 0x022 2867d36db35SAvi Kivity #define SVM_EXIT_READ_DR3 0x023 2877d36db35SAvi Kivity #define SVM_EXIT_READ_DR4 0x024 2887d36db35SAvi Kivity #define SVM_EXIT_READ_DR5 0x025 2897d36db35SAvi Kivity #define SVM_EXIT_READ_DR6 0x026 2907d36db35SAvi Kivity #define SVM_EXIT_READ_DR7 0x027 2917d36db35SAvi Kivity #define SVM_EXIT_WRITE_DR0 0x030 2927d36db35SAvi Kivity #define SVM_EXIT_WRITE_DR1 0x031 2937d36db35SAvi Kivity #define SVM_EXIT_WRITE_DR2 0x032 2947d36db35SAvi Kivity #define SVM_EXIT_WRITE_DR3 0x033 2957d36db35SAvi Kivity #define SVM_EXIT_WRITE_DR4 0x034 2967d36db35SAvi Kivity #define SVM_EXIT_WRITE_DR5 0x035 2977d36db35SAvi Kivity #define SVM_EXIT_WRITE_DR6 0x036 2987d36db35SAvi Kivity #define SVM_EXIT_WRITE_DR7 0x037 2997d36db35SAvi Kivity #define SVM_EXIT_EXCP_BASE 0x040 3007d36db35SAvi Kivity #define SVM_EXIT_INTR 0x060 3017d36db35SAvi Kivity #define SVM_EXIT_NMI 0x061 3027d36db35SAvi Kivity #define SVM_EXIT_SMI 0x062 3037d36db35SAvi Kivity #define SVM_EXIT_INIT 0x063 3047d36db35SAvi Kivity #define SVM_EXIT_VINTR 0x064 3057d36db35SAvi Kivity #define SVM_EXIT_CR0_SEL_WRITE 0x065 3067d36db35SAvi Kivity #define SVM_EXIT_IDTR_READ 0x066 3077d36db35SAvi Kivity #define SVM_EXIT_GDTR_READ 0x067 3087d36db35SAvi Kivity #define SVM_EXIT_LDTR_READ 0x068 3097d36db35SAvi Kivity #define SVM_EXIT_TR_READ 0x069 3107d36db35SAvi Kivity #define SVM_EXIT_IDTR_WRITE 0x06a 3117d36db35SAvi Kivity #define SVM_EXIT_GDTR_WRITE 0x06b 3127d36db35SAvi Kivity #define SVM_EXIT_LDTR_WRITE 0x06c 3137d36db35SAvi Kivity #define SVM_EXIT_TR_WRITE 0x06d 3147d36db35SAvi Kivity #define SVM_EXIT_RDTSC 0x06e 3157d36db35SAvi Kivity #define SVM_EXIT_RDPMC 0x06f 3167d36db35SAvi Kivity #define SVM_EXIT_PUSHF 0x070 3177d36db35SAvi Kivity #define SVM_EXIT_POPF 0x071 3187d36db35SAvi Kivity #define SVM_EXIT_CPUID 0x072 3197d36db35SAvi Kivity #define SVM_EXIT_RSM 0x073 3207d36db35SAvi Kivity #define SVM_EXIT_IRET 0x074 3217d36db35SAvi Kivity #define SVM_EXIT_SWINT 0x075 3227d36db35SAvi Kivity #define SVM_EXIT_INVD 0x076 3237d36db35SAvi Kivity #define SVM_EXIT_PAUSE 0x077 3247d36db35SAvi Kivity #define SVM_EXIT_HLT 0x078 3257d36db35SAvi Kivity #define SVM_EXIT_INVLPG 0x079 3267d36db35SAvi Kivity #define SVM_EXIT_INVLPGA 0x07a 3277d36db35SAvi Kivity #define SVM_EXIT_IOIO 0x07b 3287d36db35SAvi Kivity #define SVM_EXIT_MSR 0x07c 3297d36db35SAvi Kivity #define SVM_EXIT_TASK_SWITCH 0x07d 3307d36db35SAvi Kivity #define SVM_EXIT_FERR_FREEZE 0x07e 3317d36db35SAvi Kivity #define SVM_EXIT_SHUTDOWN 0x07f 3327d36db35SAvi Kivity #define SVM_EXIT_VMRUN 0x080 3337d36db35SAvi Kivity #define SVM_EXIT_VMMCALL 0x081 3347d36db35SAvi Kivity #define SVM_EXIT_VMLOAD 0x082 3357d36db35SAvi Kivity #define SVM_EXIT_VMSAVE 0x083 3367d36db35SAvi Kivity #define SVM_EXIT_STGI 0x084 3377d36db35SAvi Kivity #define SVM_EXIT_CLGI 0x085 3387d36db35SAvi Kivity #define SVM_EXIT_SKINIT 0x086 3397d36db35SAvi Kivity #define SVM_EXIT_RDTSCP 0x087 3407d36db35SAvi Kivity #define SVM_EXIT_ICEBP 0x088 3417d36db35SAvi Kivity #define SVM_EXIT_WBINVD 0x089 3427d36db35SAvi Kivity #define SVM_EXIT_MONITOR 0x08a 3437d36db35SAvi Kivity #define SVM_EXIT_MWAIT 0x08b 3447d36db35SAvi Kivity #define SVM_EXIT_MWAIT_COND 0x08c 3457d36db35SAvi Kivity #define SVM_EXIT_NPF 0x400 3467d36db35SAvi Kivity 3477d36db35SAvi Kivity #define SVM_EXIT_ERR -1 3487d36db35SAvi Kivity 3497d36db35SAvi Kivity #define SVM_CR0_SELECTIVE_MASK (X86_CR0_TS | X86_CR0_MP) 3507d36db35SAvi Kivity 351eae10e8fSKrish Sadhukhan #define SVM_CR0_RESERVED_MASK 0xffffffff00000000U 3526d0ecbf6SKrish Sadhukhan #define SVM_CR3_LONG_MBZ_MASK 0xfff0000000000000U 3536d0ecbf6SKrish Sadhukhan #define SVM_CR3_LONG_RESERVED_MASK 0x0000000000000fe7U 3546d0ecbf6SKrish Sadhukhan #define SVM_CR3_PAE_LEGACY_RESERVED_MASK 0x0000000000000007U 355d30973c3SWei Huang #define SVM_CR4_LEGACY_RESERVED_MASK 0xff08e000U 356d30973c3SWei Huang #define SVM_CR4_RESERVED_MASK 0xffffffffff08e000U 357eae10e8fSKrish Sadhukhan #define SVM_DR6_RESERVED_MASK 0xffffffffffff1ff0U 358eae10e8fSKrish Sadhukhan #define SVM_DR7_RESERVED_MASK 0xffffffff0000cc00U 359eae10e8fSKrish Sadhukhan #define SVM_EFER_RESERVED_MASK 0xffffffffffff0200U 360eae10e8fSKrish Sadhukhan 361ad879127SKrish Sadhukhan #define MSR_BITMAP_SIZE 8192 3627d36db35SAvi Kivity 363537d39dfSMaxim Levitsky #define LBR_CTL_ENABLE_MASK BIT_ULL(0) 364537d39dfSMaxim Levitsky 365ad879127SKrish Sadhukhan struct svm_test { 366ad879127SKrish Sadhukhan const char *name; 367ad879127SKrish Sadhukhan bool (*supported)(void); 368ad879127SKrish Sadhukhan void (*prepare)(struct svm_test *test); 369ad879127SKrish Sadhukhan void (*prepare_gif_clear)(struct svm_test *test); 370ad879127SKrish Sadhukhan void (*guest_func)(struct svm_test *test); 371ad879127SKrish Sadhukhan bool (*finished)(struct svm_test *test); 372ad879127SKrish Sadhukhan bool (*succeeded)(struct svm_test *test); 373ad879127SKrish Sadhukhan int exits; 374ad879127SKrish Sadhukhan ulong scratch; 3758660d1b5SKrish Sadhukhan /* Alternative test interface. */ 3768660d1b5SKrish Sadhukhan void (*v2)(void); 37748f67910SCathy Avery int on_vcpu; 37848f67910SCathy Avery bool on_vcpu_done; 379ad879127SKrish Sadhukhan }; 380ad879127SKrish Sadhukhan 381ad879127SKrish Sadhukhan struct regs { 382ad879127SKrish Sadhukhan u64 rax; 383ad879127SKrish Sadhukhan u64 rbx; 384ad879127SKrish Sadhukhan u64 rcx; 385ad879127SKrish Sadhukhan u64 rdx; 386ad879127SKrish Sadhukhan u64 cr2; 387ad879127SKrish Sadhukhan u64 rbp; 388ad879127SKrish Sadhukhan u64 rsi; 389ad879127SKrish Sadhukhan u64 rdi; 390ad879127SKrish Sadhukhan u64 r8; 391ad879127SKrish Sadhukhan u64 r9; 392ad879127SKrish Sadhukhan u64 r10; 393ad879127SKrish Sadhukhan u64 r11; 394ad879127SKrish Sadhukhan u64 r12; 395ad879127SKrish Sadhukhan u64 r13; 396ad879127SKrish Sadhukhan u64 r14; 397ad879127SKrish Sadhukhan u64 r15; 398ad879127SKrish Sadhukhan u64 rflags; 399ad879127SKrish Sadhukhan }; 400ad879127SKrish Sadhukhan 4018660d1b5SKrish Sadhukhan typedef void (*test_guest_func)(struct svm_test *); 4028660d1b5SKrish Sadhukhan 403ad879127SKrish Sadhukhan u64 *npt_get_pte(u64 address); 404ad879127SKrish Sadhukhan u64 *npt_get_pde(u64 address); 405ad879127SKrish Sadhukhan u64 *npt_get_pdpe(void); 406c6405e37SNadav Amit u64 *npt_get_pml4e(void); 407ad879127SKrish Sadhukhan bool smp_supported(void); 408ad879127SKrish Sadhukhan bool default_supported(void); 409f6972bd6SLara Lazier bool vgif_supported(void); 410537d39dfSMaxim Levitsky bool lbrv_supported(void); 411ad879127SKrish Sadhukhan void default_prepare(struct svm_test *test); 412ad879127SKrish Sadhukhan void default_prepare_gif_clear(struct svm_test *test); 413ad879127SKrish Sadhukhan bool default_finished(struct svm_test *test); 414ad879127SKrish Sadhukhan bool npt_supported(void); 415ad879127SKrish Sadhukhan int get_test_stage(struct svm_test *test); 416ad879127SKrish Sadhukhan void set_test_stage(struct svm_test *test, int s); 417ad879127SKrish Sadhukhan void inc_test_stage(struct svm_test *test); 418ad879127SKrish Sadhukhan void vmcb_ident(struct vmcb *vmcb); 419ad879127SKrish Sadhukhan struct regs get_regs(void); 420ad879127SKrish Sadhukhan void vmmcall(void); 421a6495564SKrish Sadhukhan int __svm_vmrun(u64 rip); 422ea9bf4adSMaxim Levitsky void __svm_bare_vmrun(void); 4238660d1b5SKrish Sadhukhan int svm_vmrun(void); 4248660d1b5SKrish Sadhukhan void test_set_guest(test_guest_func func); 425ad879127SKrish Sadhukhan 426096cf7feSPaolo Bonzini extern struct vmcb *vmcb; 427096cf7feSPaolo Bonzini extern struct svm_test svm_tests[]; 428096cf7feSPaolo Bonzini 429*c45bccfcSMaxim Levitsky static inline void stgi(void) 430*c45bccfcSMaxim Levitsky { 431*c45bccfcSMaxim Levitsky asm volatile ("stgi"); 432*c45bccfcSMaxim Levitsky } 433*c45bccfcSMaxim Levitsky 434*c45bccfcSMaxim Levitsky static inline void clgi(void) 435*c45bccfcSMaxim Levitsky { 436*c45bccfcSMaxim Levitsky asm volatile ("clgi"); 437*c45bccfcSMaxim Levitsky } 438*c45bccfcSMaxim Levitsky 439*c45bccfcSMaxim Levitsky 440ea9bf4adSMaxim Levitsky 441ea9bf4adSMaxim Levitsky #define SAVE_GPR_C \ 442ea9bf4adSMaxim Levitsky "xchg %%rbx, regs+0x8\n\t" \ 443ea9bf4adSMaxim Levitsky "xchg %%rcx, regs+0x10\n\t" \ 444ea9bf4adSMaxim Levitsky "xchg %%rdx, regs+0x18\n\t" \ 445ea9bf4adSMaxim Levitsky "xchg %%rbp, regs+0x28\n\t" \ 446ea9bf4adSMaxim Levitsky "xchg %%rsi, regs+0x30\n\t" \ 447ea9bf4adSMaxim Levitsky "xchg %%rdi, regs+0x38\n\t" \ 448ea9bf4adSMaxim Levitsky "xchg %%r8, regs+0x40\n\t" \ 449ea9bf4adSMaxim Levitsky "xchg %%r9, regs+0x48\n\t" \ 450ea9bf4adSMaxim Levitsky "xchg %%r10, regs+0x50\n\t" \ 451ea9bf4adSMaxim Levitsky "xchg %%r11, regs+0x58\n\t" \ 452ea9bf4adSMaxim Levitsky "xchg %%r12, regs+0x60\n\t" \ 453ea9bf4adSMaxim Levitsky "xchg %%r13, regs+0x68\n\t" \ 454ea9bf4adSMaxim Levitsky "xchg %%r14, regs+0x70\n\t" \ 455ea9bf4adSMaxim Levitsky "xchg %%r15, regs+0x78\n\t" 456ea9bf4adSMaxim Levitsky 457ea9bf4adSMaxim Levitsky #define LOAD_GPR_C SAVE_GPR_C 458ea9bf4adSMaxim Levitsky 459ea9bf4adSMaxim Levitsky #define ASM_PRE_VMRUN_CMD \ 460ea9bf4adSMaxim Levitsky "vmload %%rax\n\t" \ 461ea9bf4adSMaxim Levitsky "mov regs+0x80, %%r15\n\t" \ 462ea9bf4adSMaxim Levitsky "mov %%r15, 0x170(%%rax)\n\t" \ 463ea9bf4adSMaxim Levitsky "mov regs, %%r15\n\t" \ 464ea9bf4adSMaxim Levitsky "mov %%r15, 0x1f8(%%rax)\n\t" \ 465ea9bf4adSMaxim Levitsky LOAD_GPR_C \ 466ea9bf4adSMaxim Levitsky 467ea9bf4adSMaxim Levitsky #define ASM_POST_VMRUN_CMD \ 468ea9bf4adSMaxim Levitsky SAVE_GPR_C \ 469ea9bf4adSMaxim Levitsky "mov 0x170(%%rax), %%r15\n\t" \ 470ea9bf4adSMaxim Levitsky "mov %%r15, regs+0x80\n\t" \ 471ea9bf4adSMaxim Levitsky "mov 0x1f8(%%rax), %%r15\n\t" \ 472ea9bf4adSMaxim Levitsky "mov %%r15, regs\n\t" \ 473ea9bf4adSMaxim Levitsky "vmsave %%rax\n\t" \ 474ea9bf4adSMaxim Levitsky 475ea9bf4adSMaxim Levitsky 476ea9bf4adSMaxim Levitsky 477ea9bf4adSMaxim Levitsky #define SVM_BARE_VMRUN \ 478ea9bf4adSMaxim Levitsky asm volatile ( \ 479ea9bf4adSMaxim Levitsky ASM_PRE_VMRUN_CMD \ 480ea9bf4adSMaxim Levitsky "vmrun %%rax\n\t" \ 481ea9bf4adSMaxim Levitsky ASM_POST_VMRUN_CMD \ 482ea9bf4adSMaxim Levitsky : \ 483ea9bf4adSMaxim Levitsky : "a" (virt_to_phys(vmcb)) \ 484ea9bf4adSMaxim Levitsky : "memory", "r15") \ 485ea9bf4adSMaxim Levitsky 486ad879127SKrish Sadhukhan #endif 487