svm.h 11 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407
  1. #ifndef __SVM_H
  2. #define __SVM_H
  3. #define SVM_EXIT_READ_CR0 0x000
  4. #define SVM_EXIT_READ_CR3 0x003
  5. #define SVM_EXIT_READ_CR4 0x004
  6. #define SVM_EXIT_READ_CR8 0x008
  7. #define SVM_EXIT_WRITE_CR0 0x010
  8. #define SVM_EXIT_WRITE_CR3 0x013
  9. #define SVM_EXIT_WRITE_CR4 0x014
  10. #define SVM_EXIT_WRITE_CR8 0x018
  11. #define SVM_EXIT_READ_DR0 0x020
  12. #define SVM_EXIT_READ_DR1 0x021
  13. #define SVM_EXIT_READ_DR2 0x022
  14. #define SVM_EXIT_READ_DR3 0x023
  15. #define SVM_EXIT_READ_DR4 0x024
  16. #define SVM_EXIT_READ_DR5 0x025
  17. #define SVM_EXIT_READ_DR6 0x026
  18. #define SVM_EXIT_READ_DR7 0x027
  19. #define SVM_EXIT_WRITE_DR0 0x030
  20. #define SVM_EXIT_WRITE_DR1 0x031
  21. #define SVM_EXIT_WRITE_DR2 0x032
  22. #define SVM_EXIT_WRITE_DR3 0x033
  23. #define SVM_EXIT_WRITE_DR4 0x034
  24. #define SVM_EXIT_WRITE_DR5 0x035
  25. #define SVM_EXIT_WRITE_DR6 0x036
  26. #define SVM_EXIT_WRITE_DR7 0x037
  27. #define SVM_EXIT_EXCP_BASE 0x040
  28. #define SVM_EXIT_INTR 0x060
  29. #define SVM_EXIT_NMI 0x061
  30. #define SVM_EXIT_SMI 0x062
  31. #define SVM_EXIT_INIT 0x063
  32. #define SVM_EXIT_VINTR 0x064
  33. #define SVM_EXIT_CR0_SEL_WRITE 0x065
  34. #define SVM_EXIT_IDTR_READ 0x066
  35. #define SVM_EXIT_GDTR_READ 0x067
  36. #define SVM_EXIT_LDTR_READ 0x068
  37. #define SVM_EXIT_TR_READ 0x069
  38. #define SVM_EXIT_IDTR_WRITE 0x06a
  39. #define SVM_EXIT_GDTR_WRITE 0x06b
  40. #define SVM_EXIT_LDTR_WRITE 0x06c
  41. #define SVM_EXIT_TR_WRITE 0x06d
  42. #define SVM_EXIT_RDTSC 0x06e
  43. #define SVM_EXIT_RDPMC 0x06f
  44. #define SVM_EXIT_PUSHF 0x070
  45. #define SVM_EXIT_POPF 0x071
  46. #define SVM_EXIT_CPUID 0x072
  47. #define SVM_EXIT_RSM 0x073
  48. #define SVM_EXIT_IRET 0x074
  49. #define SVM_EXIT_SWINT 0x075
  50. #define SVM_EXIT_INVD 0x076
  51. #define SVM_EXIT_PAUSE 0x077
  52. #define SVM_EXIT_HLT 0x078
  53. #define SVM_EXIT_INVLPG 0x079
  54. #define SVM_EXIT_INVLPGA 0x07a
  55. #define SVM_EXIT_IOIO 0x07b
  56. #define SVM_EXIT_MSR 0x07c
  57. #define SVM_EXIT_TASK_SWITCH 0x07d
  58. #define SVM_EXIT_FERR_FREEZE 0x07e
  59. #define SVM_EXIT_SHUTDOWN 0x07f
  60. #define SVM_EXIT_VMRUN 0x080
  61. #define SVM_EXIT_VMMCALL 0x081
  62. #define SVM_EXIT_VMLOAD 0x082
  63. #define SVM_EXIT_VMSAVE 0x083
  64. #define SVM_EXIT_STGI 0x084
  65. #define SVM_EXIT_CLGI 0x085
  66. #define SVM_EXIT_SKINIT 0x086
  67. #define SVM_EXIT_RDTSCP 0x087
  68. #define SVM_EXIT_ICEBP 0x088
  69. #define SVM_EXIT_WBINVD 0x089
  70. #define SVM_EXIT_MONITOR 0x08a
  71. #define SVM_EXIT_MWAIT 0x08b
  72. #define SVM_EXIT_MWAIT_COND 0x08c
  73. #define SVM_EXIT_XSETBV 0x08d
  74. #define SVM_EXIT_NPF 0x400
  75. #define SVM_EXIT_ERR -1
  76. #define SVM_EXIT_REASONS \
  77. { SVM_EXIT_READ_CR0, "read_cr0" }, \
  78. { SVM_EXIT_READ_CR3, "read_cr3" }, \
  79. { SVM_EXIT_READ_CR4, "read_cr4" }, \
  80. { SVM_EXIT_READ_CR8, "read_cr8" }, \
  81. { SVM_EXIT_WRITE_CR0, "write_cr0" }, \
  82. { SVM_EXIT_WRITE_CR3, "write_cr3" }, \
  83. { SVM_EXIT_WRITE_CR4, "write_cr4" }, \
  84. { SVM_EXIT_WRITE_CR8, "write_cr8" }, \
  85. { SVM_EXIT_READ_DR0, "read_dr0" }, \
  86. { SVM_EXIT_READ_DR1, "read_dr1" }, \
  87. { SVM_EXIT_READ_DR2, "read_dr2" }, \
  88. { SVM_EXIT_READ_DR3, "read_dr3" }, \
  89. { SVM_EXIT_WRITE_DR0, "write_dr0" }, \
  90. { SVM_EXIT_WRITE_DR1, "write_dr1" }, \
  91. { SVM_EXIT_WRITE_DR2, "write_dr2" }, \
  92. { SVM_EXIT_WRITE_DR3, "write_dr3" }, \
  93. { SVM_EXIT_WRITE_DR5, "write_dr5" }, \
  94. { SVM_EXIT_WRITE_DR7, "write_dr7" }, \
  95. { SVM_EXIT_EXCP_BASE + DB_VECTOR, "DB excp" }, \
  96. { SVM_EXIT_EXCP_BASE + BP_VECTOR, "BP excp" }, \
  97. { SVM_EXIT_EXCP_BASE + UD_VECTOR, "UD excp" }, \
  98. { SVM_EXIT_EXCP_BASE + PF_VECTOR, "PF excp" }, \
  99. { SVM_EXIT_EXCP_BASE + NM_VECTOR, "NM excp" }, \
  100. { SVM_EXIT_EXCP_BASE + MC_VECTOR, "MC excp" }, \
  101. { SVM_EXIT_INTR, "interrupt" }, \
  102. { SVM_EXIT_NMI, "nmi" }, \
  103. { SVM_EXIT_SMI, "smi" }, \
  104. { SVM_EXIT_INIT, "init" }, \
  105. { SVM_EXIT_VINTR, "vintr" }, \
  106. { SVM_EXIT_CPUID, "cpuid" }, \
  107. { SVM_EXIT_INVD, "invd" }, \
  108. { SVM_EXIT_HLT, "hlt" }, \
  109. { SVM_EXIT_INVLPG, "invlpg" }, \
  110. { SVM_EXIT_INVLPGA, "invlpga" }, \
  111. { SVM_EXIT_IOIO, "io" }, \
  112. { SVM_EXIT_MSR, "msr" }, \
  113. { SVM_EXIT_TASK_SWITCH, "task_switch" }, \
  114. { SVM_EXIT_SHUTDOWN, "shutdown" }, \
  115. { SVM_EXIT_VMRUN, "vmrun" }, \
  116. { SVM_EXIT_VMMCALL, "hypercall" }, \
  117. { SVM_EXIT_VMLOAD, "vmload" }, \
  118. { SVM_EXIT_VMSAVE, "vmsave" }, \
  119. { SVM_EXIT_STGI, "stgi" }, \
  120. { SVM_EXIT_CLGI, "clgi" }, \
  121. { SVM_EXIT_SKINIT, "skinit" }, \
  122. { SVM_EXIT_WBINVD, "wbinvd" }, \
  123. { SVM_EXIT_MONITOR, "monitor" }, \
  124. { SVM_EXIT_MWAIT, "mwait" }, \
  125. { SVM_EXIT_XSETBV, "xsetbv" }, \
  126. { SVM_EXIT_NPF, "npf" }
  127. #ifdef __KERNEL__
  128. enum {
  129. INTERCEPT_INTR,
  130. INTERCEPT_NMI,
  131. INTERCEPT_SMI,
  132. INTERCEPT_INIT,
  133. INTERCEPT_VINTR,
  134. INTERCEPT_SELECTIVE_CR0,
  135. INTERCEPT_STORE_IDTR,
  136. INTERCEPT_STORE_GDTR,
  137. INTERCEPT_STORE_LDTR,
  138. INTERCEPT_STORE_TR,
  139. INTERCEPT_LOAD_IDTR,
  140. INTERCEPT_LOAD_GDTR,
  141. INTERCEPT_LOAD_LDTR,
  142. INTERCEPT_LOAD_TR,
  143. INTERCEPT_RDTSC,
  144. INTERCEPT_RDPMC,
  145. INTERCEPT_PUSHF,
  146. INTERCEPT_POPF,
  147. INTERCEPT_CPUID,
  148. INTERCEPT_RSM,
  149. INTERCEPT_IRET,
  150. INTERCEPT_INTn,
  151. INTERCEPT_INVD,
  152. INTERCEPT_PAUSE,
  153. INTERCEPT_HLT,
  154. INTERCEPT_INVLPG,
  155. INTERCEPT_INVLPGA,
  156. INTERCEPT_IOIO_PROT,
  157. INTERCEPT_MSR_PROT,
  158. INTERCEPT_TASK_SWITCH,
  159. INTERCEPT_FERR_FREEZE,
  160. INTERCEPT_SHUTDOWN,
  161. INTERCEPT_VMRUN,
  162. INTERCEPT_VMMCALL,
  163. INTERCEPT_VMLOAD,
  164. INTERCEPT_VMSAVE,
  165. INTERCEPT_STGI,
  166. INTERCEPT_CLGI,
  167. INTERCEPT_SKINIT,
  168. INTERCEPT_RDTSCP,
  169. INTERCEPT_ICEBP,
  170. INTERCEPT_WBINVD,
  171. INTERCEPT_MONITOR,
  172. INTERCEPT_MWAIT,
  173. INTERCEPT_MWAIT_COND,
  174. INTERCEPT_XSETBV,
  175. };
  176. struct __attribute__ ((__packed__)) vmcb_control_area {
  177. u32 intercept_cr;
  178. u32 intercept_dr;
  179. u32 intercept_exceptions;
  180. u64 intercept;
  181. u8 reserved_1[42];
  182. u16 pause_filter_count;
  183. u64 iopm_base_pa;
  184. u64 msrpm_base_pa;
  185. u64 tsc_offset;
  186. u32 asid;
  187. u8 tlb_ctl;
  188. u8 reserved_2[3];
  189. u32 int_ctl;
  190. u32 int_vector;
  191. u32 int_state;
  192. u8 reserved_3[4];
  193. u32 exit_code;
  194. u32 exit_code_hi;
  195. u64 exit_info_1;
  196. u64 exit_info_2;
  197. u32 exit_int_info;
  198. u32 exit_int_info_err;
  199. u64 nested_ctl;
  200. u8 reserved_4[16];
  201. u32 event_inj;
  202. u32 event_inj_err;
  203. u64 nested_cr3;
  204. u64 lbr_ctl;
  205. u32 clean;
  206. u32 reserved_5;
  207. u64 next_rip;
  208. u8 insn_len;
  209. u8 insn_bytes[15];
  210. u8 reserved_6[800];
  211. };
  212. #define TLB_CONTROL_DO_NOTHING 0
  213. #define TLB_CONTROL_FLUSH_ALL_ASID 1
  214. #define TLB_CONTROL_FLUSH_ASID 3
  215. #define TLB_CONTROL_FLUSH_ASID_LOCAL 7
  216. #define V_TPR_MASK 0x0f
  217. #define V_IRQ_SHIFT 8
  218. #define V_IRQ_MASK (1 << V_IRQ_SHIFT)
  219. #define V_INTR_PRIO_SHIFT 16
  220. #define V_INTR_PRIO_MASK (0x0f << V_INTR_PRIO_SHIFT)
  221. #define V_IGN_TPR_SHIFT 20
  222. #define V_IGN_TPR_MASK (1 << V_IGN_TPR_SHIFT)
  223. #define V_INTR_MASKING_SHIFT 24
  224. #define V_INTR_MASKING_MASK (1 << V_INTR_MASKING_SHIFT)
  225. #define SVM_INTERRUPT_SHADOW_MASK 1
  226. #define SVM_IOIO_STR_SHIFT 2
  227. #define SVM_IOIO_REP_SHIFT 3
  228. #define SVM_IOIO_SIZE_SHIFT 4
  229. #define SVM_IOIO_ASIZE_SHIFT 7
  230. #define SVM_IOIO_TYPE_MASK 1
  231. #define SVM_IOIO_STR_MASK (1 << SVM_IOIO_STR_SHIFT)
  232. #define SVM_IOIO_REP_MASK (1 << SVM_IOIO_REP_SHIFT)
  233. #define SVM_IOIO_SIZE_MASK (7 << SVM_IOIO_SIZE_SHIFT)
  234. #define SVM_IOIO_ASIZE_MASK (7 << SVM_IOIO_ASIZE_SHIFT)
  235. #define SVM_VM_CR_VALID_MASK 0x001fULL
  236. #define SVM_VM_CR_SVM_LOCK_MASK 0x0008ULL
  237. #define SVM_VM_CR_SVM_DIS_MASK 0x0010ULL
  238. struct __attribute__ ((__packed__)) vmcb_seg {
  239. u16 selector;
  240. u16 attrib;
  241. u32 limit;
  242. u64 base;
  243. };
  244. struct __attribute__ ((__packed__)) vmcb_save_area {
  245. struct vmcb_seg es;
  246. struct vmcb_seg cs;
  247. struct vmcb_seg ss;
  248. struct vmcb_seg ds;
  249. struct vmcb_seg fs;
  250. struct vmcb_seg gs;
  251. struct vmcb_seg gdtr;
  252. struct vmcb_seg ldtr;
  253. struct vmcb_seg idtr;
  254. struct vmcb_seg tr;
  255. u8 reserved_1[43];
  256. u8 cpl;
  257. u8 reserved_2[4];
  258. u64 efer;
  259. u8 reserved_3[112];
  260. u64 cr4;
  261. u64 cr3;
  262. u64 cr0;
  263. u64 dr7;
  264. u64 dr6;
  265. u64 rflags;
  266. u64 rip;
  267. u8 reserved_4[88];
  268. u64 rsp;
  269. u8 reserved_5[24];
  270. u64 rax;
  271. u64 star;
  272. u64 lstar;
  273. u64 cstar;
  274. u64 sfmask;
  275. u64 kernel_gs_base;
  276. u64 sysenter_cs;
  277. u64 sysenter_esp;
  278. u64 sysenter_eip;
  279. u64 cr2;
  280. u8 reserved_6[32];
  281. u64 g_pat;
  282. u64 dbgctl;
  283. u64 br_from;
  284. u64 br_to;
  285. u64 last_excp_from;
  286. u64 last_excp_to;
  287. };
  288. struct __attribute__ ((__packed__)) vmcb {
  289. struct vmcb_control_area control;
  290. struct vmcb_save_area save;
  291. };
  292. #define SVM_CPUID_FEATURE_SHIFT 2
  293. #define SVM_CPUID_FUNC 0x8000000a
  294. #define SVM_VM_CR_SVM_DISABLE 4
  295. #define SVM_SELECTOR_S_SHIFT 4
  296. #define SVM_SELECTOR_DPL_SHIFT 5
  297. #define SVM_SELECTOR_P_SHIFT 7
  298. #define SVM_SELECTOR_AVL_SHIFT 8
  299. #define SVM_SELECTOR_L_SHIFT 9
  300. #define SVM_SELECTOR_DB_SHIFT 10
  301. #define SVM_SELECTOR_G_SHIFT 11
  302. #define SVM_SELECTOR_TYPE_MASK (0xf)
  303. #define SVM_SELECTOR_S_MASK (1 << SVM_SELECTOR_S_SHIFT)
  304. #define SVM_SELECTOR_DPL_MASK (3 << SVM_SELECTOR_DPL_SHIFT)
  305. #define SVM_SELECTOR_P_MASK (1 << SVM_SELECTOR_P_SHIFT)
  306. #define SVM_SELECTOR_AVL_MASK (1 << SVM_SELECTOR_AVL_SHIFT)
  307. #define SVM_SELECTOR_L_MASK (1 << SVM_SELECTOR_L_SHIFT)
  308. #define SVM_SELECTOR_DB_MASK (1 << SVM_SELECTOR_DB_SHIFT)
  309. #define SVM_SELECTOR_G_MASK (1 << SVM_SELECTOR_G_SHIFT)
  310. #define SVM_SELECTOR_WRITE_MASK (1 << 1)
  311. #define SVM_SELECTOR_READ_MASK SVM_SELECTOR_WRITE_MASK
  312. #define SVM_SELECTOR_CODE_MASK (1 << 3)
  313. #define INTERCEPT_CR0_READ 0
  314. #define INTERCEPT_CR3_READ 3
  315. #define INTERCEPT_CR4_READ 4
  316. #define INTERCEPT_CR8_READ 8
  317. #define INTERCEPT_CR0_WRITE (16 + 0)
  318. #define INTERCEPT_CR3_WRITE (16 + 3)
  319. #define INTERCEPT_CR4_WRITE (16 + 4)
  320. #define INTERCEPT_CR8_WRITE (16 + 8)
  321. #define INTERCEPT_DR0_READ 0
  322. #define INTERCEPT_DR1_READ 1
  323. #define INTERCEPT_DR2_READ 2
  324. #define INTERCEPT_DR3_READ 3
  325. #define INTERCEPT_DR4_READ 4
  326. #define INTERCEPT_DR5_READ 5
  327. #define INTERCEPT_DR6_READ 6
  328. #define INTERCEPT_DR7_READ 7
  329. #define INTERCEPT_DR0_WRITE (16 + 0)
  330. #define INTERCEPT_DR1_WRITE (16 + 1)
  331. #define INTERCEPT_DR2_WRITE (16 + 2)
  332. #define INTERCEPT_DR3_WRITE (16 + 3)
  333. #define INTERCEPT_DR4_WRITE (16 + 4)
  334. #define INTERCEPT_DR5_WRITE (16 + 5)
  335. #define INTERCEPT_DR6_WRITE (16 + 6)
  336. #define INTERCEPT_DR7_WRITE (16 + 7)
  337. #define SVM_EVTINJ_VEC_MASK 0xff
  338. #define SVM_EVTINJ_TYPE_SHIFT 8
  339. #define SVM_EVTINJ_TYPE_MASK (7 << SVM_EVTINJ_TYPE_SHIFT)
  340. #define SVM_EVTINJ_TYPE_INTR (0 << SVM_EVTINJ_TYPE_SHIFT)
  341. #define SVM_EVTINJ_TYPE_NMI (2 << SVM_EVTINJ_TYPE_SHIFT)
  342. #define SVM_EVTINJ_TYPE_EXEPT (3 << SVM_EVTINJ_TYPE_SHIFT)
  343. #define SVM_EVTINJ_TYPE_SOFT (4 << SVM_EVTINJ_TYPE_SHIFT)
  344. #define SVM_EVTINJ_VALID (1 << 31)
  345. #define SVM_EVTINJ_VALID_ERR (1 << 11)
  346. #define SVM_EXITINTINFO_VEC_MASK SVM_EVTINJ_VEC_MASK
  347. #define SVM_EXITINTINFO_TYPE_MASK SVM_EVTINJ_TYPE_MASK
  348. #define SVM_EXITINTINFO_TYPE_INTR SVM_EVTINJ_TYPE_INTR
  349. #define SVM_EXITINTINFO_TYPE_NMI SVM_EVTINJ_TYPE_NMI
  350. #define SVM_EXITINTINFO_TYPE_EXEPT SVM_EVTINJ_TYPE_EXEPT
  351. #define SVM_EXITINTINFO_TYPE_SOFT SVM_EVTINJ_TYPE_SOFT
  352. #define SVM_EXITINTINFO_VALID SVM_EVTINJ_VALID
  353. #define SVM_EXITINTINFO_VALID_ERR SVM_EVTINJ_VALID_ERR
  354. #define SVM_EXITINFOSHIFT_TS_REASON_IRET 36
  355. #define SVM_EXITINFOSHIFT_TS_REASON_JMP 38
  356. #define SVM_EXITINFOSHIFT_TS_HAS_ERROR_CODE 44
  357. #define SVM_EXITINFO_REG_MASK 0x0F
  358. #define SVM_CR0_SELECTIVE_MASK (X86_CR0_TS | X86_CR0_MP)
  359. #define SVM_VMLOAD ".byte 0x0f, 0x01, 0xda"
  360. #define SVM_VMRUN ".byte 0x0f, 0x01, 0xd8"
  361. #define SVM_VMSAVE ".byte 0x0f, 0x01, 0xdb"
  362. #define SVM_CLGI ".byte 0x0f, 0x01, 0xdd"
  363. #define SVM_STGI ".byte 0x0f, 0x01, 0xdc"
  364. #define SVM_INVLPGA ".byte 0x0f, 0x01, 0xdf"
  365. #endif
  366. #endif