aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/kvm/svm.h
diff options
context:
space:
mode:
authorAvi Kivity <avi@qumranet.com>2006-12-10 05:21:36 -0500
committerLinus Torvalds <torvalds@woody.osdl.org>2006-12-10 12:57:22 -0500
commit6aa8b732ca01c3d7a54e93f4d701b8aabbe60fb7 (patch)
tree23fcbe6f4918cacdae26d513a2bd13e91d8b4c38 /drivers/kvm/svm.h
parentf5f1a24a2caa299bb7d294aee92d7dd3410d9ed7 (diff)
[PATCH] kvm: userspace interface
web site: http://kvm.sourceforge.net mailing list: kvm-devel@lists.sourceforge.net (http://lists.sourceforge.net/lists/listinfo/kvm-devel) The following patchset adds a driver for Intel's hardware virtualization extensions to the x86 architecture. The driver adds a character device (/dev/kvm) that exposes the virtualization capabilities to userspace. Using this driver, a process can run a virtual machine (a "guest") in a fully virtualized PC containing its own virtual hard disks, network adapters, and display. Using this driver, one can start multiple virtual machines on a host. Each virtual machine is a process on the host; a virtual cpu is a thread in that process. kill(1), nice(1), top(1) work as expected. In effect, the driver adds a third execution mode to the existing two: we now have kernel mode, user mode, and guest mode. Guest mode has its own address space mapping guest physical memory (which is accessible to user mode by mmap()ing /dev/kvm). Guest mode has no access to any I/O devices; any such access is intercepted and directed to user mode for emulation. The driver supports i386 and x86_64 hosts and guests. All combinations are allowed except x86_64 guest on i386 host. For i386 guests and hosts, both pae and non-pae paging modes are supported. SMP hosts and UP guests are supported. At the moment only Intel hardware is supported, but AMD virtualization support is being worked on. Performance currently is non-stellar due to the naive implementation of the mmu virtualization, which throws away most of the shadow page table entries every context switch. We plan to address this in two ways: - cache shadow page tables across tlb flushes - wait until AMD and Intel release processors with nested page tables Currently a virtual desktop is responsive but consumes a lot of CPU. Under Windows I tried playing pinball and watching a few flash movies; with a recent CPU one can hardly feel the virtualization. Linux/X is slower, probably due to X being in a separate process. In addition to the driver, you need a slightly modified qemu to provide I/O device emulation and the BIOS. Caveats (akpm: might no longer be true): - The Windows install currently bluescreens due to a problem with the virtual APIC. We are working on a fix. A temporary workaround is to use an existing image or install through qemu - Windows 64-bit does not work. That's also true for qemu, so it's probably a problem with the device model. [bero@arklinux.org: build fix] [simon.kagstrom@bth.se: build fix, other fixes] [uril@qumranet.com: KVM: Expose interrupt bitmap] [akpm@osdl.org: i386 build fix] [mingo@elte.hu: i386 fixes] [rdreier@cisco.com: add log levels to all printks] [randy.dunlap@oracle.com: Fix sparse NULL and C99 struct init warnings] [anthony@codemonkey.ws: KVM: AMD SVM: 32-bit host support] Signed-off-by: Yaniv Kamay <yaniv@qumranet.com> Signed-off-by: Avi Kivity <avi@qumranet.com> Cc: Simon Kagstrom <simon.kagstrom@bth.se> Cc: Bernhard Rosenkraenzer <bero@arklinux.org> Signed-off-by: Uri Lublin <uril@qumranet.com> Cc: Ingo Molnar <mingo@elte.hu> Cc: Roland Dreier <rolandd@cisco.com> Signed-off-by: Randy Dunlap <randy.dunlap@oracle.com> Signed-off-by: Anthony Liguori <anthony@codemonkey.ws> Signed-off-by: Andrew Morton <akpm@osdl.org> Signed-off-by: Linus Torvalds <torvalds@osdl.org>
Diffstat (limited to 'drivers/kvm/svm.h')
-rw-r--r--drivers/kvm/svm.h315
1 files changed, 315 insertions, 0 deletions
diff --git a/drivers/kvm/svm.h b/drivers/kvm/svm.h
new file mode 100644
index 000000000000..df731c3fb588
--- /dev/null
+++ b/drivers/kvm/svm.h
@@ -0,0 +1,315 @@
1#ifndef __SVM_H
2#define __SVM_H
3
4enum {
5 INTERCEPT_INTR,
6 INTERCEPT_NMI,
7 INTERCEPT_SMI,
8 INTERCEPT_INIT,
9 INTERCEPT_VINTR,
10 INTERCEPT_SELECTIVE_CR0,
11 INTERCEPT_STORE_IDTR,
12 INTERCEPT_STORE_GDTR,
13 INTERCEPT_STORE_LDTR,
14 INTERCEPT_STORE_TR,
15 INTERCEPT_LOAD_IDTR,
16 INTERCEPT_LOAD_GDTR,
17 INTERCEPT_LOAD_LDTR,
18 INTERCEPT_LOAD_TR,
19 INTERCEPT_RDTSC,
20 INTERCEPT_RDPMC,
21 INTERCEPT_PUSHF,
22 INTERCEPT_POPF,
23 INTERCEPT_CPUID,
24 INTERCEPT_RSM,
25 INTERCEPT_IRET,
26 INTERCEPT_INTn,
27 INTERCEPT_INVD,
28 INTERCEPT_PAUSE,
29 INTERCEPT_HLT,
30 INTERCEPT_INVLPG,
31 INTERCEPT_INVLPGA,
32 INTERCEPT_IOIO_PROT,
33 INTERCEPT_MSR_PROT,
34 INTERCEPT_TASK_SWITCH,
35 INTERCEPT_FERR_FREEZE,
36 INTERCEPT_SHUTDOWN,
37 INTERCEPT_VMRUN,
38 INTERCEPT_VMMCALL,
39 INTERCEPT_VMLOAD,
40 INTERCEPT_VMSAVE,
41 INTERCEPT_STGI,
42 INTERCEPT_CLGI,
43 INTERCEPT_SKINIT,
44 INTERCEPT_RDTSCP,
45 INTERCEPT_ICEBP,
46 INTERCEPT_WBINVD,
47};
48
49
50struct __attribute__ ((__packed__)) vmcb_control_area {
51 u16 intercept_cr_read;
52 u16 intercept_cr_write;
53 u16 intercept_dr_read;
54 u16 intercept_dr_write;
55 u32 intercept_exceptions;
56 u64 intercept;
57 u8 reserved_1[44];
58 u64 iopm_base_pa;
59 u64 msrpm_base_pa;
60 u64 tsc_offset;
61 u32 asid;
62 u8 tlb_ctl;
63 u8 reserved_2[3];
64 u32 int_ctl;
65 u32 int_vector;
66 u32 int_state;
67 u8 reserved_3[4];
68 u32 exit_code;
69 u32 exit_code_hi;
70 u64 exit_info_1;
71 u64 exit_info_2;
72 u32 exit_int_info;
73 u32 exit_int_info_err;
74 u64 nested_ctl;
75 u8 reserved_4[16];
76 u32 event_inj;
77 u32 event_inj_err;
78 u64 nested_cr3;
79 u64 lbr_ctl;
80 u8 reserved_5[832];
81};
82
83
84#define TLB_CONTROL_DO_NOTHING 0
85#define TLB_CONTROL_FLUSH_ALL_ASID 1
86
87#define V_TPR_MASK 0x0f
88
89#define V_IRQ_SHIFT 8
90#define V_IRQ_MASK (1 << V_IRQ_SHIFT)
91
92#define V_INTR_PRIO_SHIFT 16
93#define V_INTR_PRIO_MASK (0x0f << V_INTR_PRIO_SHIFT)
94
95#define V_IGN_TPR_SHIFT 20
96#define V_IGN_TPR_MASK (1 << V_IGN_TPR_SHIFT)
97
98#define V_INTR_MASKING_SHIFT 24
99#define V_INTR_MASKING_MASK (1 << V_INTR_MASKING_SHIFT)
100
101#define SVM_INTERRUPT_SHADOW_MASK 1
102
103#define SVM_IOIO_STR_SHIFT 2
104#define SVM_IOIO_REP_SHIFT 3
105#define SVM_IOIO_SIZE_SHIFT 4
106#define SVM_IOIO_ASIZE_SHIFT 7
107
108#define SVM_IOIO_TYPE_MASK 1
109#define SVM_IOIO_STR_MASK (1 << SVM_IOIO_STR_SHIFT)
110#define SVM_IOIO_REP_MASK (1 << SVM_IOIO_REP_SHIFT)
111#define SVM_IOIO_SIZE_MASK (7 << SVM_IOIO_SIZE_SHIFT)
112#define SVM_IOIO_ASIZE_MASK (7 << SVM_IOIO_ASIZE_SHIFT)
113
114struct __attribute__ ((__packed__)) vmcb_seg {
115 u16 selector;
116 u16 attrib;
117 u32 limit;
118 u64 base;
119};
120
121struct __attribute__ ((__packed__)) vmcb_save_area {
122 struct vmcb_seg es;
123 struct vmcb_seg cs;
124 struct vmcb_seg ss;
125 struct vmcb_seg ds;
126 struct vmcb_seg fs;
127 struct vmcb_seg gs;
128 struct vmcb_seg gdtr;
129 struct vmcb_seg ldtr;
130 struct vmcb_seg idtr;
131 struct vmcb_seg tr;
132 u8 reserved_1[43];
133 u8 cpl;
134 u8 reserved_2[4];
135 u64 efer;
136 u8 reserved_3[112];
137 u64 cr4;
138 u64 cr3;
139 u64 cr0;
140 u64 dr7;
141 u64 dr6;
142 u64 rflags;
143 u64 rip;
144 u8 reserved_4[88];
145 u64 rsp;
146 u8 reserved_5[24];
147 u64 rax;
148 u64 star;
149 u64 lstar;
150 u64 cstar;
151 u64 sfmask;
152 u64 kernel_gs_base;
153 u64 sysenter_cs;
154 u64 sysenter_esp;
155 u64 sysenter_eip;
156 u64 cr2;
157 u8 reserved_6[32];
158 u64 g_pat;
159 u64 dbgctl;
160 u64 br_from;
161 u64 br_to;
162 u64 last_excp_from;
163 u64 last_excp_to;
164};
165
166struct __attribute__ ((__packed__)) vmcb {
167 struct vmcb_control_area control;
168 struct vmcb_save_area save;
169};
170
171#define SVM_CPUID_FEATURE_SHIFT 2
172#define SVM_CPUID_FUNC 0x8000000a
173
174#define MSR_EFER_SVME_MASK (1ULL << 12)
175#define MSR_VM_HSAVE_PA 0xc0010117ULL
176
177#define SVM_SELECTOR_S_SHIFT 4
178#define SVM_SELECTOR_DPL_SHIFT 5
179#define SVM_SELECTOR_P_SHIFT 7
180#define SVM_SELECTOR_AVL_SHIFT 8
181#define SVM_SELECTOR_L_SHIFT 9
182#define SVM_SELECTOR_DB_SHIFT 10
183#define SVM_SELECTOR_G_SHIFT 11
184
185#define SVM_SELECTOR_TYPE_MASK (0xf)
186#define SVM_SELECTOR_S_MASK (1 << SVM_SELECTOR_S_SHIFT)
187#define SVM_SELECTOR_DPL_MASK (3 << SVM_SELECTOR_DPL_SHIFT)
188#define SVM_SELECTOR_P_MASK (1 << SVM_SELECTOR_P_SHIFT)
189#define SVM_SELECTOR_AVL_MASK (1 << SVM_SELECTOR_AVL_SHIFT)
190#define SVM_SELECTOR_L_MASK (1 << SVM_SELECTOR_L_SHIFT)
191#define SVM_SELECTOR_DB_MASK (1 << SVM_SELECTOR_DB_SHIFT)
192#define SVM_SELECTOR_G_MASK (1 << SVM_SELECTOR_G_SHIFT)
193
194#define SVM_SELECTOR_WRITE_MASK (1 << 1)
195#define SVM_SELECTOR_READ_MASK SVM_SELECTOR_WRITE_MASK
196#define SVM_SELECTOR_CODE_MASK (1 << 3)
197
198#define INTERCEPT_CR0_MASK 1
199#define INTERCEPT_CR3_MASK (1 << 3)
200#define INTERCEPT_CR4_MASK (1 << 4)
201
202#define INTERCEPT_DR0_MASK 1
203#define INTERCEPT_DR1_MASK (1 << 1)
204#define INTERCEPT_DR2_MASK (1 << 2)
205#define INTERCEPT_DR3_MASK (1 << 3)
206#define INTERCEPT_DR4_MASK (1 << 4)
207#define INTERCEPT_DR5_MASK (1 << 5)
208#define INTERCEPT_DR6_MASK (1 << 6)
209#define INTERCEPT_DR7_MASK (1 << 7)
210
211#define SVM_EVTINJ_VEC_MASK 0xff
212
213#define SVM_EVTINJ_TYPE_SHIFT 8
214#define SVM_EVTINJ_TYPE_MASK (7 << SVM_EVTINJ_TYPE_SHIFT)
215
216#define SVM_EVTINJ_TYPE_INTR (0 << SVM_EVTINJ_TYPE_SHIFT)
217#define SVM_EVTINJ_TYPE_NMI (2 << SVM_EVTINJ_TYPE_SHIFT)
218#define SVM_EVTINJ_TYPE_EXEPT (3 << SVM_EVTINJ_TYPE_SHIFT)
219#define SVM_EVTINJ_TYPE_SOFT (4 << SVM_EVTINJ_TYPE_SHIFT)
220
221#define SVM_EVTINJ_VALID (1 << 31)
222#define SVM_EVTINJ_VALID_ERR (1 << 11)
223
224#define SVM_EXITINTINFO_VEC_MASK SVM_EVTINJ_VEC_MASK
225
226#define SVM_EXITINTINFO_TYPE_INTR SVM_EVTINJ_TYPE_INTR
227#define SVM_EXITINTINFO_TYPE_NMI SVM_EVTINJ_TYPE_NMI
228#define SVM_EXITINTINFO_TYPE_EXEPT SVM_EVTINJ_TYPE_EXEPT
229#define SVM_EXITINTINFO_TYPE_SOFT SVM_EVTINJ_TYPE_SOFT
230
231#define SVM_EXITINTINFO_VALID SVM_EVTINJ_VALID
232#define SVM_EXITINTINFO_VALID_ERR SVM_EVTINJ_VALID_ERR
233
234#define SVM_EXIT_READ_CR0 0x000
235#define SVM_EXIT_READ_CR3 0x003
236#define SVM_EXIT_READ_CR4 0x004
237#define SVM_EXIT_READ_CR8 0x008
238#define SVM_EXIT_WRITE_CR0 0x010
239#define SVM_EXIT_WRITE_CR3 0x013
240#define SVM_EXIT_WRITE_CR4 0x014
241#define SVM_EXIT_WRITE_CR8 0x018
242#define SVM_EXIT_READ_DR0 0x020
243#define SVM_EXIT_READ_DR1 0x021
244#define SVM_EXIT_READ_DR2 0x022
245#define SVM_EXIT_READ_DR3 0x023
246#define SVM_EXIT_READ_DR4 0x024
247#define SVM_EXIT_READ_DR5 0x025
248#define SVM_EXIT_READ_DR6 0x026
249#define SVM_EXIT_READ_DR7 0x027
250#define SVM_EXIT_WRITE_DR0 0x030
251#define SVM_EXIT_WRITE_DR1 0x031
252#define SVM_EXIT_WRITE_DR2 0x032
253#define SVM_EXIT_WRITE_DR3 0x033
254#define SVM_EXIT_WRITE_DR4 0x034
255#define SVM_EXIT_WRITE_DR5 0x035
256#define SVM_EXIT_WRITE_DR6 0x036
257#define SVM_EXIT_WRITE_DR7 0x037
258#define SVM_EXIT_EXCP_BASE 0x040
259#define SVM_EXIT_INTR 0x060
260#define SVM_EXIT_NMI 0x061
261#define SVM_EXIT_SMI 0x062
262#define SVM_EXIT_INIT 0x063
263#define SVM_EXIT_VINTR 0x064
264#define SVM_EXIT_CR0_SEL_WRITE 0x065
265#define SVM_EXIT_IDTR_READ 0x066
266#define SVM_EXIT_GDTR_READ 0x067
267#define SVM_EXIT_LDTR_READ 0x068
268#define SVM_EXIT_TR_READ 0x069
269#define SVM_EXIT_IDTR_WRITE 0x06a
270#define SVM_EXIT_GDTR_WRITE 0x06b
271#define SVM_EXIT_LDTR_WRITE 0x06c
272#define SVM_EXIT_TR_WRITE 0x06d
273#define SVM_EXIT_RDTSC 0x06e
274#define SVM_EXIT_RDPMC 0x06f
275#define SVM_EXIT_PUSHF 0x070
276#define SVM_EXIT_POPF 0x071
277#define SVM_EXIT_CPUID 0x072
278#define SVM_EXIT_RSM 0x073
279#define SVM_EXIT_IRET 0x074
280#define SVM_EXIT_SWINT 0x075
281#define SVM_EXIT_INVD 0x076
282#define SVM_EXIT_PAUSE 0x077
283#define SVM_EXIT_HLT 0x078
284#define SVM_EXIT_INVLPG 0x079
285#define SVM_EXIT_INVLPGA 0x07a
286#define SVM_EXIT_IOIO 0x07b
287#define SVM_EXIT_MSR 0x07c
288#define SVM_EXIT_TASK_SWITCH 0x07d
289#define SVM_EXIT_FERR_FREEZE 0x07e
290#define SVM_EXIT_SHUTDOWN 0x07f
291#define SVM_EXIT_VMRUN 0x080
292#define SVM_EXIT_VMMCALL 0x081
293#define SVM_EXIT_VMLOAD 0x082
294#define SVM_EXIT_VMSAVE 0x083
295#define SVM_EXIT_STGI 0x084
296#define SVM_EXIT_CLGI 0x085
297#define SVM_EXIT_SKINIT 0x086
298#define SVM_EXIT_RDTSCP 0x087
299#define SVM_EXIT_ICEBP 0x088
300#define SVM_EXIT_WBINVD 0x089
301#define SVM_EXIT_NPF 0x400
302
303#define SVM_EXIT_ERR -1
304
305#define SVM_CR0_SELECTIVE_MASK (1 << 3 | 1) // TS and MP
306
307#define SVM_VMLOAD ".byte 0x0f, 0x01, 0xda"
308#define SVM_VMRUN ".byte 0x0f, 0x01, 0xd8"
309#define SVM_VMSAVE ".byte 0x0f, 0x01, 0xdb"
310#define SVM_CLGI ".byte 0x0f, 0x01, 0xdd"
311#define SVM_STGI ".byte 0x0f, 0x01, 0xdc"
312#define SVM_INVLPGA ".byte 0x0f, 0x01, 0xdf"
313
314#endif
315