]> rtime.felk.cvut.cz Git - jailhouse.git/blob - hypervisor/arch/x86/include/asm/svm.h
x86: Intercept #AC and #DB to prevent guest-triggered microcode loops
[jailhouse.git] / hypervisor / arch / x86 / include / asm / svm.h
1 /*
2  * Jailhouse, a Linux-based partitioning hypervisor
3  *
4  * Copyright (c) 2005-2007, Advanced Micro Devices, Inc
5  * Copyright (c) 2004, Intel Corporation.
6  * Copyright (c) Valentine Sinitsyn, 2014
7  *
8  * Authors:
9  *  Valentine Sinitsyn <valentine.sinitsyn@gmail.com>
10  *
11  * This file is partially derived from
12  * xvisor/arch/x86/cpu/x86_64/include/vm/amd_vmcb.h, which comes with
13  * Xvisor 0.2 (http://xhypervisor.org).
14  *
15  * Copyright (c) 2005-2007, Advanced Micro Devices, Inc
16  * Copyright (c) 2004, Intel Corporation.
17  *
18  * This work is licensed under the terms of the GNU GPL, version 2.  See
19  * the COPYING file in the top-level directory.
20  */
21
22 #ifndef _JAILHOUSE_ASM_SVM_H
23 #define _JAILHOUSE_ASM_SVM_H
24
25 #include <jailhouse/types.h>
26
27 #define EFER_SVME               (1UL << 12)
28 #define VM_CR_SVMDIS            (1UL << 4)
29
30 #define MSR_VM_CR               0xc0010114
31 #define MSR_VM_HSAVE_PA         0xc0010117
32
33 #define SVM_MSRPM_0000          0
34 #define SVM_MSRPM_C000          1
35 #define SVM_MSRPM_C001          2
36 #define SVM_MSRPM_RESV          3
37
38 #define SVM_TLB_FLUSH_ALL       0x01
39 #define SVM_TLB_FLUSH_GUEST     0x03
40
41 #define NPT_PAGE_DIR_LEVELS     4
42
43 #define SVM_EVENTINJ_EXCEPTION  (3UL << 8)
44 #define SVM_EVENTINJ_ERR_VALID  (1UL << 11)
45 #define SVM_EVENTINJ_VALID      (1UL << 31)
46
47 struct svm_segment {
48         u16 selector;
49         u16 access_rights;
50         u32 limit;
51         u64 base;
52 } __attribute__((packed));
53
54 /* general 1 intercepts */
55 enum generic_interrupt_1_bits {
56         GENERAL1_INTERCEPT_INTR          = 1 << 0,
57         GENERAL1_INTERCEPT_NMI           = 1 << 1,
58         GENERAL1_INTERCEPT_SMI           = 1 << 2,
59         GENERAL1_INTERCEPT_INIT          = 1 << 3,
60         GENERAL1_INTERCEPT_VINTR         = 1 << 4,
61         GENERAL1_INTERCEPT_CR0_SEL_WRITE = 1 << 5,
62         GENERAL1_INTERCEPT_IDTR_READ     = 1 << 6,
63         GENERAL1_INTERCEPT_GDTR_READ     = 1 << 7,
64         GENERAL1_INTERCEPT_LDTR_READ     = 1 << 8,
65         GENERAL1_INTERCEPT_TR_READ       = 1 << 9,
66         GENERAL1_INTERCEPT_IDTR_WRITE    = 1 << 10,
67         GENERAL1_INTERCEPT_GDTR_WRITE    = 1 << 11,
68         GENERAL1_INTERCEPT_LDTR_WRITE    = 1 << 12,
69         GENERAL1_INTERCEPT_TR_WRITE      = 1 << 13,
70         GENERAL1_INTERCEPT_RDTSC         = 1 << 14,
71         GENERAL1_INTERCEPT_RDPMC         = 1 << 15,
72         GENERAL1_INTERCEPT_PUSHF         = 1 << 16,
73         GENERAL1_INTERCEPT_POPF          = 1 << 17,
74         GENERAL1_INTERCEPT_CPUID         = 1 << 18,
75         GENERAL1_INTERCEPT_RSM           = 1 << 19,
76         GENERAL1_INTERCEPT_IRET          = 1 << 20,
77         GENERAL1_INTERCEPT_SWINT         = 1 << 21,
78         GENERAL1_INTERCEPT_INVD          = 1 << 22,
79         GENERAL1_INTERCEPT_PAUSE         = 1 << 23,
80         GENERAL1_INTERCEPT_HLT           = 1 << 24,
81         GENERAL1_INTERCEPT_INVLPG        = 1 << 25,
82         GENERAL1_INTERCEPT_INVLPGA       = 1 << 26,
83         GENERAL1_INTERCEPT_IOIO_PROT     = 1 << 27,
84         GENERAL1_INTERCEPT_MSR_PROT      = 1 << 28,
85         GENERAL1_INTERCEPT_TASK_SWITCH   = 1 << 29,
86         GENERAL1_INTERCEPT_FERR_FREEZE   = 1 << 30,
87         GENERAL1_INTERCEPT_SHUTDOWN_EVT  = 1 << 31
88 };
89
90 /* general 2 intercepts */
91 enum generic_interrupts_2_bits {
92         GENERAL2_INTERCEPT_VMRUN   = 1 << 0,
93         GENERAL2_INTERCEPT_VMMCALL = 1 << 1,
94         GENERAL2_INTERCEPT_VMLOAD  = 1 << 2,
95         GENERAL2_INTERCEPT_VMSAVE  = 1 << 3,
96         GENERAL2_INTERCEPT_STGI    = 1 << 4,
97         GENERAL2_INTERCEPT_CLGI    = 1 << 5,
98         GENERAL2_INTERCEPT_SKINIT  = 1 << 6,
99         GENERAL2_INTERCEPT_RDTSCP  = 1 << 7,
100         GENERAL2_INTERCEPT_ICEBP   = 1 << 8,
101         GENERAL2_INTERCEPT_WBINVD  = 1 << 9,
102         GENERAL2_INTERCEPT_MONITOR = 1 << 10,
103         GENERAL2_INTERCEPT_MWAIT   = 1 << 11,
104         GENERAL2_INTERCEPT_MWAIT_CONDITIONAL = 1 << 12
105 };
106
107 enum vm_exit_code {
108         /* control register read exitcodes */
109         VMEXIT_CR0_READ    =   0,
110         VMEXIT_CR1_READ    =   1,
111         VMEXIT_CR2_READ    =   2,
112         VMEXIT_CR3_READ    =   3,
113         VMEXIT_CR4_READ    =   4,
114         VMEXIT_CR5_READ    =   5,
115         VMEXIT_CR6_READ    =   6,
116         VMEXIT_CR7_READ    =   7,
117         VMEXIT_CR8_READ    =   8,
118         VMEXIT_CR9_READ    =   9,
119         VMEXIT_CR10_READ   =  10,
120         VMEXIT_CR11_READ   =  11,
121         VMEXIT_CR12_READ   =  12,
122         VMEXIT_CR13_READ   =  13,
123         VMEXIT_CR14_READ   =  14,
124         VMEXIT_CR15_READ   =  15,
125
126         /* control register write exitcodes */
127         VMEXIT_CR0_WRITE   =  16,
128         VMEXIT_CR1_WRITE   =  17,
129         VMEXIT_CR2_WRITE   =  18,
130         VMEXIT_CR3_WRITE   =  19,
131         VMEXIT_CR4_WRITE   =  20,
132         VMEXIT_CR5_WRITE   =  21,
133         VMEXIT_CR6_WRITE   =  22,
134         VMEXIT_CR7_WRITE   =  23,
135         VMEXIT_CR8_WRITE   =  24,
136         VMEXIT_CR9_WRITE   =  25,
137         VMEXIT_CR10_WRITE  =  26,
138         VMEXIT_CR11_WRITE  =  27,
139         VMEXIT_CR12_WRITE  =  28,
140         VMEXIT_CR13_WRITE  =  29,
141         VMEXIT_CR14_WRITE  =  30,
142         VMEXIT_CR15_WRITE  =  31,
143
144         /* debug register read exitcodes */
145         VMEXIT_DR0_READ    =  32,
146         VMEXIT_DR1_READ    =  33,
147         VMEXIT_DR2_READ    =  34,
148         VMEXIT_DR3_READ    =  35,
149         VMEXIT_DR4_READ    =  36,
150         VMEXIT_DR5_READ    =  37,
151         VMEXIT_DR6_READ    =  38,
152         VMEXIT_DR7_READ    =  39,
153         VMEXIT_DR8_READ    =  40,
154         VMEXIT_DR9_READ    =  41,
155         VMEXIT_DR10_READ   =  42,
156         VMEXIT_DR11_READ   =  43,
157         VMEXIT_DR12_READ   =  44,
158         VMEXIT_DR13_READ   =  45,
159         VMEXIT_DR14_READ   =  46,
160         VMEXIT_DR15_READ   =  47,
161
162         /* debug register write exitcodes */
163         VMEXIT_DR0_WRITE   =  48,
164         VMEXIT_DR1_WRITE   =  49,
165         VMEXIT_DR2_WRITE   =  50,
166         VMEXIT_DR3_WRITE   =  51,
167         VMEXIT_DR4_WRITE   =  52,
168         VMEXIT_DR5_WRITE   =  53,
169         VMEXIT_DR6_WRITE   =  54,
170         VMEXIT_DR7_WRITE   =  55,
171         VMEXIT_DR8_WRITE   =  56,
172         VMEXIT_DR9_WRITE   =  57,
173         VMEXIT_DR10_WRITE  =  58,
174         VMEXIT_DR11_WRITE  =  59,
175         VMEXIT_DR12_WRITE  =  60,
176         VMEXIT_DR13_WRITE  =  61,
177         VMEXIT_DR14_WRITE  =  62,
178         VMEXIT_DR15_WRITE  =  63,
179
180         /* processor exception exitcodes (VMEXIT_EXCP[0-31]) */
181         VMEXIT_EXCEPTION_DE      =      64, /* divide-by-zero-error */
182         VMEXIT_EXCEPTION_DB      =      65, /* debug */
183         VMEXIT_EXCEPTION_NMI     =      66, /* non-maskable-interrupt */
184         VMEXIT_EXCEPTION_BP      =      67, /* breakpoint */
185         VMEXIT_EXCEPTION_OF      =      68, /* overflow */
186         VMEXIT_EXCEPTION_BR      =      69, /* bound-range */
187         VMEXIT_EXCEPTION_UD      =      70, /* invalid-opcode*/
188         VMEXIT_EXCEPTION_NM      =      71, /* device-not-available */
189         VMEXIT_EXCEPTION_DF      =      72, /* double-fault */
190         VMEXIT_EXCEPTION_09      =      73, /* unsupported (reserved) */
191         VMEXIT_EXCEPTION_TS      =      74, /* invalid-tss */
192         VMEXIT_EXCEPTION_NP      =      75, /* segment-not-present */
193         VMEXIT_EXCEPTION_SS      =      76, /* stack */
194         VMEXIT_EXCEPTION_GP      =      77, /* general-protection */
195         VMEXIT_EXCEPTION_PF      =      78, /* page-fault */
196         VMEXIT_EXCEPTION_15      =      79, /* reserved */
197         VMEXIT_EXCEPTION_MF      =      80, /* x87 floating-point exception-pending */
198         VMEXIT_EXCEPTION_AC      =      81, /* alignment-check */
199         VMEXIT_EXCEPTION_MC      =      82, /* machine-check */
200         VMEXIT_EXCEPTION_XF      =      83, /* simd floating-point */
201
202         /* exceptions 20-31 (exitcodes 84-95) are reserved */
203
204         /* ...and the rest of the #VMEXITs */
205         VMEXIT_INTR                     =  96,
206         VMEXIT_NMI                      =  97,
207         VMEXIT_SMI                      =  98,
208         VMEXIT_INIT                     =  99,
209         VMEXIT_VINTR                    = 100,
210         VMEXIT_CR0_SEL_WRITE            = 101,
211         VMEXIT_IDTR_READ                = 102,
212         VMEXIT_GDTR_READ                = 103,
213         VMEXIT_LDTR_READ                = 104,
214         VMEXIT_TR_READ                  = 105,
215         VMEXIT_IDTR_WRITE               = 106,
216         VMEXIT_GDTR_WRITE               = 107,
217         VMEXIT_LDTR_WRITE               = 108,
218         VMEXIT_TR_WRITE                 = 109,
219         VMEXIT_RDTSC                    = 110,
220         VMEXIT_RDPMC                    = 111,
221         VMEXIT_PUSHF                    = 112,
222         VMEXIT_POPF                     = 113,
223         VMEXIT_CPUID                    = 114,
224         VMEXIT_RSM                      = 115,
225         VMEXIT_IRET                     = 116,
226         VMEXIT_SWINT                    = 117,
227         VMEXIT_INVD                     = 118,
228         VMEXIT_PAUSE                    = 119,
229         VMEXIT_HLT                      = 120,
230         VMEXIT_INVLPG                   = 121,
231         VMEXIT_INVLPGA                  = 122,
232         VMEXIT_IOIO                     = 123,
233         VMEXIT_MSR                      = 124,
234         VMEXIT_TASK_SWITCH              = 125,
235         VMEXIT_FERR_FREEZE              = 126,
236         VMEXIT_SHUTDOWN                 = 127,
237         VMEXIT_VMRUN                    = 128,
238         VMEXIT_VMMCALL                  = 129,
239         VMEXIT_VMLOAD                   = 130,
240         VMEXIT_VMSAVE                   = 131,
241         VMEXIT_STGI                     = 132,
242         VMEXIT_CLGI                     = 133,
243         VMEXIT_SKINIT                   = 134,
244         VMEXIT_RDTSCP                   = 135,
245         VMEXIT_ICEBP                    = 136,
246         VMEXIT_WBINVD                   = 137,
247         VMEXIT_MONITOR                  = 138,
248         VMEXIT_MWAIT                    = 139,
249         VMEXIT_MWAIT_CONDITIONAL        = 140,
250         VMEXIT_XSETBV                   = 141,
251         VMEXIT_NPF                      = 1024, /* nested paging fault */
252         VMEXIT_INVALID                  =  -1
253 };
254
255 enum clean_bits {
256         CLEAN_BITS_I    = 1 << 0,
257         CLEAN_BITS_IOPM = 1 << 1,
258         CLEAN_BITS_ASID = 1 << 2,
259         CLEAN_BITS_TPR  = 1 << 3,
260         CLEAN_BITS_NP   = 1 << 4,
261         CLEAN_BITS_CRX  = 1 << 5,
262         CLEAN_BITS_DRX  = 1 << 6,
263         CLEAN_BITS_DT   = 1 << 7,
264         CLEAN_BITS_SEG  = 1 << 8,
265         CLEAN_BITS_CR2  = 1 << 9,
266         CLEAN_BITS_LBR  = 1 << 10,
267         CLEAN_BITS_AVIC = 1 << 11
268 };
269
270 typedef u64 vintr_t;
271 typedef u64 lbrctrl_t;
272
273 struct vmcb {
274         u32 cr_intercepts;              /* offset 0x00 */
275         u32 dr_intercepts;              /* offset 0x04 */
276         u32 exception_intercepts;       /* offset 0x08 */
277         u32 general1_intercepts;        /* offset 0x0C */
278         u32 general2_intercepts;        /* offset 0x10 */
279         u32 res01;                      /* offset 0x14 */
280         u64 res02;                      /* offset 0x18 */
281         u64 res03;                      /* offset 0x20 */
282         u64 res04;                      /* offset 0x28 */
283         u64 res05;                      /* offset 0x30 */
284         u32 res06;                      /* offset 0x38 */
285         u16 res06a;                     /* offset 0x3C */
286         u16 pause_filter_count;         /* offset 0x3E */
287         u64 iopm_base_pa;               /* offset 0x40 */
288         u64 msrpm_base_pa;              /* offset 0x48 */
289         u64 tsc_offset;                 /* offset 0x50 */
290         u32 guest_asid;                 /* offset 0x58 */
291         u8 tlb_control;                 /* offset 0x5C */
292         u8 res07[3];
293         vintr_t vintr;                  /* offset 0x60 */
294         u64 interrupt_shadow;           /* offset 0x68 */
295         u64 exitcode;                   /* offset 0x70 */
296         u64 exitinfo1;                  /* offset 0x78 */
297         u64 exitinfo2;                  /* offset 0x80 */
298         u64 exitintinfo;                /* offset 0x88 */
299         u64 np_enable;                  /* offset 0x90 */
300         u64 res08[2];
301         u32 eventinj;                   /* offset 0xA8 */
302         u32 eventinj_err;               /* offset 0xAC */
303         u64 n_cr3;                      /* offset 0xB0 */
304         lbrctrl_t lbr_control;          /* offset 0xB8 */
305         u64 clean_bits;                 /* offset 0xC0 */
306         u64 nextrip;                    /* offset 0xC8 */
307         u8 bytes_fetched;               /* offset 0xD0 */
308         u8 guest_bytes[15];
309         u64 res10a[100];                /* offset 0xE0 pad to save area */
310
311         struct svm_segment es;          /* offset 1024 */
312         struct svm_segment cs;
313         struct svm_segment ss;
314         struct svm_segment ds;
315         struct svm_segment fs;
316         struct svm_segment gs;
317         struct svm_segment gdtr;
318         struct svm_segment ldtr;
319         struct svm_segment idtr;
320         struct svm_segment tr;
321
322         u64 res10[5];
323         u8 res11[3];
324         u8 cpl;
325         u32 res12;
326         u64 efer;                       /* offset 1024 + 0xD0 */
327         u64 res13[14];
328         u64 cr4;                        /* loffset 1024 + 0x148 */
329         u64 cr3;
330         u64 cr0;
331         u64 dr7;
332         u64 dr6;
333         u64 rflags;
334         u64 rip;
335         u64 res14[11];
336         u64 rsp;
337         u64 res15[3];
338         u64 rax;
339         u64 star;
340         u64 lstar;
341         u64 cstar;
342         u64 sfmask;
343         u64 kerngsbase;
344         u64 sysenter_cs;
345         u64 sysenter_esp;
346         u64 sysenter_eip;
347         u64 cr2;
348         u64 pdpe0;
349         u64 pdpe1;
350         u64 pdpe2;
351         u64 pdpe3;
352         u64 g_pat;
353         u64 debugctlmsr;
354         u64 lastbranchfromip;
355         u64 lastbranchtoip;
356         u64 lastintfromip;
357         u64 lastinttoip;
358         u64 res16[301];
359 } __attribute__((packed));
360
361 #endif