svm.h 7.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315
  1. #ifndef __SVM_H
  2. #define __SVM_H
  3. enum {
  4. INTERCEPT_INTR,
  5. INTERCEPT_NMI,
  6. INTERCEPT_SMI,
  7. INTERCEPT_INIT,
  8. INTERCEPT_VINTR,
  9. INTERCEPT_SELECTIVE_CR0,
  10. INTERCEPT_STORE_IDTR,
  11. INTERCEPT_STORE_GDTR,
  12. INTERCEPT_STORE_LDTR,
  13. INTERCEPT_STORE_TR,
  14. INTERCEPT_LOAD_IDTR,
  15. INTERCEPT_LOAD_GDTR,
  16. INTERCEPT_LOAD_LDTR,
  17. INTERCEPT_LOAD_TR,
  18. INTERCEPT_RDTSC,
  19. INTERCEPT_RDPMC,
  20. INTERCEPT_PUSHF,
  21. INTERCEPT_POPF,
  22. INTERCEPT_CPUID,
  23. INTERCEPT_RSM,
  24. INTERCEPT_IRET,
  25. INTERCEPT_INTn,
  26. INTERCEPT_INVD,
  27. INTERCEPT_PAUSE,
  28. INTERCEPT_HLT,
  29. INTERCEPT_INVLPG,
  30. INTERCEPT_INVLPGA,
  31. INTERCEPT_IOIO_PROT,
  32. INTERCEPT_MSR_PROT,
  33. INTERCEPT_TASK_SWITCH,
  34. INTERCEPT_FERR_FREEZE,
  35. INTERCEPT_SHUTDOWN,
  36. INTERCEPT_VMRUN,
  37. INTERCEPT_VMMCALL,
  38. INTERCEPT_VMLOAD,
  39. INTERCEPT_VMSAVE,
  40. INTERCEPT_STGI,
  41. INTERCEPT_CLGI,
  42. INTERCEPT_SKINIT,
  43. INTERCEPT_RDTSCP,
  44. INTERCEPT_ICEBP,
  45. INTERCEPT_WBINVD,
  46. };
  47. struct __attribute__ ((__packed__)) vmcb_control_area {
  48. u16 intercept_cr_read;
  49. u16 intercept_cr_write;
  50. u16 intercept_dr_read;
  51. u16 intercept_dr_write;
  52. u32 intercept_exceptions;
  53. u64 intercept;
  54. u8 reserved_1[44];
  55. u64 iopm_base_pa;
  56. u64 msrpm_base_pa;
  57. u64 tsc_offset;
  58. u32 asid;
  59. u8 tlb_ctl;
  60. u8 reserved_2[3];
  61. u32 int_ctl;
  62. u32 int_vector;
  63. u32 int_state;
  64. u8 reserved_3[4];
  65. u32 exit_code;
  66. u32 exit_code_hi;
  67. u64 exit_info_1;
  68. u64 exit_info_2;
  69. u32 exit_int_info;
  70. u32 exit_int_info_err;
  71. u64 nested_ctl;
  72. u8 reserved_4[16];
  73. u32 event_inj;
  74. u32 event_inj_err;
  75. u64 nested_cr3;
  76. u64 lbr_ctl;
  77. u8 reserved_5[832];
  78. };
  79. #define TLB_CONTROL_DO_NOTHING 0
  80. #define TLB_CONTROL_FLUSH_ALL_ASID 1
  81. #define V_TPR_MASK 0x0f
  82. #define V_IRQ_SHIFT 8
  83. #define V_IRQ_MASK (1 << V_IRQ_SHIFT)
  84. #define V_INTR_PRIO_SHIFT 16
  85. #define V_INTR_PRIO_MASK (0x0f << V_INTR_PRIO_SHIFT)
  86. #define V_IGN_TPR_SHIFT 20
  87. #define V_IGN_TPR_MASK (1 << V_IGN_TPR_SHIFT)
  88. #define V_INTR_MASKING_SHIFT 24
  89. #define V_INTR_MASKING_MASK (1 << V_INTR_MASKING_SHIFT)
  90. #define SVM_INTERRUPT_SHADOW_MASK 1
  91. #define SVM_IOIO_STR_SHIFT 2
  92. #define SVM_IOIO_REP_SHIFT 3
  93. #define SVM_IOIO_SIZE_SHIFT 4
  94. #define SVM_IOIO_ASIZE_SHIFT 7
  95. #define SVM_IOIO_TYPE_MASK 1
  96. #define SVM_IOIO_STR_MASK (1 << SVM_IOIO_STR_SHIFT)
  97. #define SVM_IOIO_REP_MASK (1 << SVM_IOIO_REP_SHIFT)
  98. #define SVM_IOIO_SIZE_MASK (7 << SVM_IOIO_SIZE_SHIFT)
  99. #define SVM_IOIO_ASIZE_MASK (7 << SVM_IOIO_ASIZE_SHIFT)
  100. struct __attribute__ ((__packed__)) vmcb_seg {
  101. u16 selector;
  102. u16 attrib;
  103. u32 limit;
  104. u64 base;
  105. };
  106. struct __attribute__ ((__packed__)) vmcb_save_area {
  107. struct vmcb_seg es;
  108. struct vmcb_seg cs;
  109. struct vmcb_seg ss;
  110. struct vmcb_seg ds;
  111. struct vmcb_seg fs;
  112. struct vmcb_seg gs;
  113. struct vmcb_seg gdtr;
  114. struct vmcb_seg ldtr;
  115. struct vmcb_seg idtr;
  116. struct vmcb_seg tr;
  117. u8 reserved_1[43];
  118. u8 cpl;
  119. u8 reserved_2[4];
  120. u64 efer;
  121. u8 reserved_3[112];
  122. u64 cr4;
  123. u64 cr3;
  124. u64 cr0;
  125. u64 dr7;
  126. u64 dr6;
  127. u64 rflags;
  128. u64 rip;
  129. u8 reserved_4[88];
  130. u64 rsp;
  131. u8 reserved_5[24];
  132. u64 rax;
  133. u64 star;
  134. u64 lstar;
  135. u64 cstar;
  136. u64 sfmask;
  137. u64 kernel_gs_base;
  138. u64 sysenter_cs;
  139. u64 sysenter_esp;
  140. u64 sysenter_eip;
  141. u64 cr2;
  142. u8 reserved_6[32];
  143. u64 g_pat;
  144. u64 dbgctl;
  145. u64 br_from;
  146. u64 br_to;
  147. u64 last_excp_from;
  148. u64 last_excp_to;
  149. };
  150. struct __attribute__ ((__packed__)) vmcb {
  151. struct vmcb_control_area control;
  152. struct vmcb_save_area save;
  153. };
  154. #define SVM_CPUID_FEATURE_SHIFT 2
  155. #define SVM_CPUID_FUNC 0x8000000a
  156. #define MSR_EFER_SVME_MASK (1ULL << 12)
  157. #define MSR_VM_HSAVE_PA 0xc0010117ULL
  158. #define SVM_SELECTOR_S_SHIFT 4
  159. #define SVM_SELECTOR_DPL_SHIFT 5
  160. #define SVM_SELECTOR_P_SHIFT 7
  161. #define SVM_SELECTOR_AVL_SHIFT 8
  162. #define SVM_SELECTOR_L_SHIFT 9
  163. #define SVM_SELECTOR_DB_SHIFT 10
  164. #define SVM_SELECTOR_G_SHIFT 11
  165. #define SVM_SELECTOR_TYPE_MASK (0xf)
  166. #define SVM_SELECTOR_S_MASK (1 << SVM_SELECTOR_S_SHIFT)
  167. #define SVM_SELECTOR_DPL_MASK (3 << SVM_SELECTOR_DPL_SHIFT)
  168. #define SVM_SELECTOR_P_MASK (1 << SVM_SELECTOR_P_SHIFT)
  169. #define SVM_SELECTOR_AVL_MASK (1 << SVM_SELECTOR_AVL_SHIFT)
  170. #define SVM_SELECTOR_L_MASK (1 << SVM_SELECTOR_L_SHIFT)
  171. #define SVM_SELECTOR_DB_MASK (1 << SVM_SELECTOR_DB_SHIFT)
  172. #define SVM_SELECTOR_G_MASK (1 << SVM_SELECTOR_G_SHIFT)
  173. #define SVM_SELECTOR_WRITE_MASK (1 << 1)
  174. #define SVM_SELECTOR_READ_MASK SVM_SELECTOR_WRITE_MASK
  175. #define SVM_SELECTOR_CODE_MASK (1 << 3)
  176. #define INTERCEPT_CR0_MASK 1
  177. #define INTERCEPT_CR3_MASK (1 << 3)
  178. #define INTERCEPT_CR4_MASK (1 << 4)
  179. #define INTERCEPT_DR0_MASK 1
  180. #define INTERCEPT_DR1_MASK (1 << 1)
  181. #define INTERCEPT_DR2_MASK (1 << 2)
  182. #define INTERCEPT_DR3_MASK (1 << 3)
  183. #define INTERCEPT_DR4_MASK (1 << 4)
  184. #define INTERCEPT_DR5_MASK (1 << 5)
  185. #define INTERCEPT_DR6_MASK (1 << 6)
  186. #define INTERCEPT_DR7_MASK (1 << 7)
  187. #define SVM_EVTINJ_VEC_MASK 0xff
  188. #define SVM_EVTINJ_TYPE_SHIFT 8
  189. #define SVM_EVTINJ_TYPE_MASK (7 << SVM_EVTINJ_TYPE_SHIFT)
  190. #define SVM_EVTINJ_TYPE_INTR (0 << SVM_EVTINJ_TYPE_SHIFT)
  191. #define SVM_EVTINJ_TYPE_NMI (2 << SVM_EVTINJ_TYPE_SHIFT)
  192. #define SVM_EVTINJ_TYPE_EXEPT (3 << SVM_EVTINJ_TYPE_SHIFT)
  193. #define SVM_EVTINJ_TYPE_SOFT (4 << SVM_EVTINJ_TYPE_SHIFT)
  194. #define SVM_EVTINJ_VALID (1 << 31)
  195. #define SVM_EVTINJ_VALID_ERR (1 << 11)
  196. #define SVM_EXITINTINFO_VEC_MASK SVM_EVTINJ_VEC_MASK
  197. #define SVM_EXITINTINFO_TYPE_INTR SVM_EVTINJ_TYPE_INTR
  198. #define SVM_EXITINTINFO_TYPE_NMI SVM_EVTINJ_TYPE_NMI
  199. #define SVM_EXITINTINFO_TYPE_EXEPT SVM_EVTINJ_TYPE_EXEPT
  200. #define SVM_EXITINTINFO_TYPE_SOFT SVM_EVTINJ_TYPE_SOFT
  201. #define SVM_EXITINTINFO_VALID SVM_EVTINJ_VALID
  202. #define SVM_EXITINTINFO_VALID_ERR SVM_EVTINJ_VALID_ERR
  203. #define SVM_EXIT_READ_CR0 0x000
  204. #define SVM_EXIT_READ_CR3 0x003
  205. #define SVM_EXIT_READ_CR4 0x004
  206. #define SVM_EXIT_READ_CR8 0x008
  207. #define SVM_EXIT_WRITE_CR0 0x010
  208. #define SVM_EXIT_WRITE_CR3 0x013
  209. #define SVM_EXIT_WRITE_CR4 0x014
  210. #define SVM_EXIT_WRITE_CR8 0x018
  211. #define SVM_EXIT_READ_DR0 0x020
  212. #define SVM_EXIT_READ_DR1 0x021
  213. #define SVM_EXIT_READ_DR2 0x022
  214. #define SVM_EXIT_READ_DR3 0x023
  215. #define SVM_EXIT_READ_DR4 0x024
  216. #define SVM_EXIT_READ_DR5 0x025
  217. #define SVM_EXIT_READ_DR6 0x026
  218. #define SVM_EXIT_READ_DR7 0x027
  219. #define SVM_EXIT_WRITE_DR0 0x030
  220. #define SVM_EXIT_WRITE_DR1 0x031
  221. #define SVM_EXIT_WRITE_DR2 0x032
  222. #define SVM_EXIT_WRITE_DR3 0x033
  223. #define SVM_EXIT_WRITE_DR4 0x034
  224. #define SVM_EXIT_WRITE_DR5 0x035
  225. #define SVM_EXIT_WRITE_DR6 0x036
  226. #define SVM_EXIT_WRITE_DR7 0x037
  227. #define SVM_EXIT_EXCP_BASE 0x040
  228. #define SVM_EXIT_INTR 0x060
  229. #define SVM_EXIT_NMI 0x061
  230. #define SVM_EXIT_SMI 0x062
  231. #define SVM_EXIT_INIT 0x063
  232. #define SVM_EXIT_VINTR 0x064
  233. #define SVM_EXIT_CR0_SEL_WRITE 0x065
  234. #define SVM_EXIT_IDTR_READ 0x066
  235. #define SVM_EXIT_GDTR_READ 0x067
  236. #define SVM_EXIT_LDTR_READ 0x068
  237. #define SVM_EXIT_TR_READ 0x069
  238. #define SVM_EXIT_IDTR_WRITE 0x06a
  239. #define SVM_EXIT_GDTR_WRITE 0x06b
  240. #define SVM_EXIT_LDTR_WRITE 0x06c
  241. #define SVM_EXIT_TR_WRITE 0x06d
  242. #define SVM_EXIT_RDTSC 0x06e
  243. #define SVM_EXIT_RDPMC 0x06f
  244. #define SVM_EXIT_PUSHF 0x070
  245. #define SVM_EXIT_POPF 0x071
  246. #define SVM_EXIT_CPUID 0x072
  247. #define SVM_EXIT_RSM 0x073
  248. #define SVM_EXIT_IRET 0x074
  249. #define SVM_EXIT_SWINT 0x075
  250. #define SVM_EXIT_INVD 0x076
  251. #define SVM_EXIT_PAUSE 0x077
  252. #define SVM_EXIT_HLT 0x078
  253. #define SVM_EXIT_INVLPG 0x079
  254. #define SVM_EXIT_INVLPGA 0x07a
  255. #define SVM_EXIT_IOIO 0x07b
  256. #define SVM_EXIT_MSR 0x07c
  257. #define SVM_EXIT_TASK_SWITCH 0x07d
  258. #define SVM_EXIT_FERR_FREEZE 0x07e
  259. #define SVM_EXIT_SHUTDOWN 0x07f
  260. #define SVM_EXIT_VMRUN 0x080
  261. #define SVM_EXIT_VMMCALL 0x081
  262. #define SVM_EXIT_VMLOAD 0x082
  263. #define SVM_EXIT_VMSAVE 0x083
  264. #define SVM_EXIT_STGI 0x084
  265. #define SVM_EXIT_CLGI 0x085
  266. #define SVM_EXIT_SKINIT 0x086
  267. #define SVM_EXIT_RDTSCP 0x087
  268. #define SVM_EXIT_ICEBP 0x088
  269. #define SVM_EXIT_WBINVD 0x089
  270. #define SVM_EXIT_NPF 0x400
  271. #define SVM_EXIT_ERR -1
  272. #define SVM_CR0_SELECTIVE_MASK (1 << 3 | 1) // TS and MP
  273. #define SVM_VMLOAD ".byte 0x0f, 0x01, 0xda"
  274. #define SVM_VMRUN ".byte 0x0f, 0x01, 0xd8"
  275. #define SVM_VMSAVE ".byte 0x0f, 0x01, 0xdb"
  276. #define SVM_CLGI ".byte 0x0f, 0x01, 0xdd"
  277. #define SVM_STGI ".byte 0x0f, 0x01, 0xdc"
  278. #define SVM_INVLPGA ".byte 0x0f, 0x01, 0xdf"
  279. #endif