]> rtime.felk.cvut.cz Git - l4.git/blob - l4/pkg/l4sys/include/__vm-svm.h
Inital import
[l4.git] / l4 / pkg / l4sys / include / __vm-svm.h
1 /**
2  * \internal
3  * \file
4  * \brief X86 virtualization interface.
5  */
6 /*
7  * (c) 2008-2009 Technische Universität Dresden
8  * This file is part of TUD:OS and distributed under the terms of the
9  * GNU General Public License 2.
10  * Please see the COPYING-GPL-2 file for details.
11  *
12  * As a special exception, you may use this file as part of a free software
13  * library without restriction.  Specifically, if other files instantiate
14  * templates or use macros or inline functions from this file, or you compile
15  * this file and link it with other files to produce an executable, this
16  * file does not by itself cause the resulting executable to be covered by
17  * the GNU General Public License.  This exception does not however
18  * invalidate any other reasons why the executable file might be covered by
19  * the GNU General Public License.
20  */
21 #pragma once
22
23 #include <l4/sys/ipc.h>
24 #include <l4/sys/task.h>
25
26 /**
27  * \defgroup l4_vm_svm_api VM API for SVM
28  * \brief Virtual machine API for SVM.
29  * \ingroup l4_vm_api
30  */
31
32
33 /**
34  * \brief VMCB structure for SVM VMs
35  * \ingroup l4_vm_svm_api
36  */
37 struct l4_vm_svm_vmcb_control_area
38 {
39   l4_uint16_t intercept_rd_crX;
40   l4_uint16_t intercept_wr_crX;
41
42   l4_uint16_t intercept_rd_drX;
43   l4_uint16_t intercept_wr_drX;
44
45   l4_uint32_t intercept_exceptions;
46
47   l4_uint32_t intercept_instruction0;
48   l4_uint32_t intercept_instruction1;
49
50   l4_uint8_t _reserved0[44];
51
52   l4_uint64_t iopm_base_pa;
53   l4_uint64_t msrpm_base_pa;
54   l4_uint64_t tsc_offset;
55   l4_uint64_t guest_asid_tlb_ctl;
56   l4_uint64_t interrupt_ctl;
57   l4_uint64_t interrupt_shadow;
58   l4_uint64_t exitcode;
59   l4_uint64_t exitinfo1;
60   l4_uint64_t exitinfo2;
61   l4_uint64_t exitintinfo;
62   l4_uint64_t np_enable;
63
64   l4_uint8_t _reserved1[16];
65
66   l4_uint64_t eventinj;
67   l4_uint64_t n_cr3;
68   l4_uint64_t lbr_virtualization_enable;
69
70   l4_uint8_t _reserved2[832];
71 } __attribute__((packed));
72
73 /**
74  * \brief State save area segment selector struct
75  * \ingroup l4_vm_svm_api
76  */
77 struct l4_vm_svm_vmcb_state_save_area_seg
78 {
79   l4_uint16_t selector;
80   l4_uint16_t attrib;
81   l4_uint32_t limit;
82   l4_uint64_t base;
83 } __attribute__((packed));
84
85 /**
86  * \brief State save area structure for SVM VMs
87  * \ingroup l4_vm_svm_api
88  */
89 struct l4_vm_svm_vmcb_state_save_area
90 {
91   struct l4_vm_svm_vmcb_state_save_area_seg es;
92   struct l4_vm_svm_vmcb_state_save_area_seg cs;
93   struct l4_vm_svm_vmcb_state_save_area_seg ss;
94   struct l4_vm_svm_vmcb_state_save_area_seg ds;
95   struct l4_vm_svm_vmcb_state_save_area_seg fs;
96   struct l4_vm_svm_vmcb_state_save_area_seg gs;
97   struct l4_vm_svm_vmcb_state_save_area_seg gdtr;
98   struct l4_vm_svm_vmcb_state_save_area_seg ldtr;
99   struct l4_vm_svm_vmcb_state_save_area_seg idtr;
100   struct l4_vm_svm_vmcb_state_save_area_seg tr;
101
102   l4_uint8_t _reserved0[43];
103
104   l4_uint8_t cpl;
105
106   l4_uint32_t _reserved1;
107
108   l4_uint64_t efer;
109
110   l4_uint8_t _reserved2[112];
111
112   l4_uint64_t cr4;
113   l4_uint64_t cr3;
114   l4_uint64_t cr0;
115   l4_uint64_t dr7;
116   l4_uint64_t dr6;
117   l4_uint64_t rflags;
118   l4_uint64_t rip;
119
120   l4_uint8_t _reserved3[88];
121
122   l4_uint64_t rsp;
123
124   l4_uint8_t _reserved4[24];
125
126   l4_uint64_t rax;
127   l4_uint64_t star;
128   l4_uint64_t lstar;
129   l4_uint64_t cstar;
130   l4_uint64_t sfmask;
131   l4_uint64_t kernelgsbase;
132   l4_uint64_t sysenter_cs;
133   l4_uint64_t sysenter_esp;
134   l4_uint64_t sysenter_eip;
135   l4_uint64_t cr2;
136
137   l4_uint8_t _reserved5[32];
138
139   l4_uint64_t g_pat;
140   l4_uint64_t dbgctl;
141   l4_uint64_t br_from;
142   l4_uint64_t br_to;
143   l4_uint64_t lastexcpfrom;
144   l4_uint64_t last_excpto;
145
146   l4_uint8_t _reserved6[2408];
147 } __attribute__((packed));
148
149
150 /**
151  * \brief Control structure for SVM VMs
152  * \ingroup l4_vm_svm_api
153  */
154 struct l4_vm_svm_vmcb
155 {
156   struct l4_vm_svm_vmcb_control_area    control_area;
157   struct l4_vm_svm_vmcb_state_save_area state_save_area;
158 };
159
160 /**
161  * \brief Run a VM
162  * \ingroup l4_vm_svm_api
163  *
164  * \param vm         Capability selector for VM
165  * \param vmcb_fpage VMCB
166  * \param gpregs     General purpose registers
167  *
168  * \note SVM only for now
169  */
170 L4_INLINE l4_msgtag_t
171 l4_vm_run_svm(l4_cap_idx_t vm, l4_fpage_t vmcb_fpage,
172               struct l4_vm_svm_gpregs *gpregs) L4_NOTHROW;
173
174 /**
175  * \internal
176  * \ingroup l4_vm_svm_api
177  */
178 L4_INLINE l4_msgtag_t
179 l4_vm_run_svm_u(l4_cap_idx_t vm_task, l4_fpage_t const vmcb_fpage,
180                 struct l4_vm_svm_gpregs *gpregs, l4_utcb_t *u) L4_NOTHROW;
181
182
183 /**
184  * \internal
185  * \brief Operations on task objects.
186  * \ingroup l4_vm_svm_api
187  */
188 enum
189 {
190   L4_VM_RUN_OP    = L4_TASK_VM_OPS + 0    /* Run a VM */
191 };
192
193
194 /****** Implementations ****************/
195
196 L4_INLINE l4_msgtag_t
197 l4_vm_run_svm_u(l4_cap_idx_t vm_task, l4_fpage_t const vmcb_fpage,
198                 struct l4_vm_svm_gpregs *gpregs, l4_utcb_t *u) L4_NOTHROW
199 {
200   l4_msgtag_t tag;
201   l4_msg_regs_t *v = l4_utcb_mr_u(u);
202   enum { GPREGS_WORDS = sizeof(*gpregs) / sizeof(l4_umword_t), };
203   v->mr[0]  = L4_VM_RUN_OP;
204
205   __builtin_memcpy(&v->mr[1], gpregs, sizeof(*gpregs));
206   v->mr[1 + GPREGS_WORDS] = l4_map_control(0, 0, 0);
207   v->mr[2 + GPREGS_WORDS] = vmcb_fpage.raw;
208
209   tag = l4_ipc_call(vm_task, u,
210                     l4_msgtag(L4_PROTO_TASK, 1 + GPREGS_WORDS, 1, 0),
211                     L4_IPC_NEVER);
212
213   __builtin_memcpy(gpregs, &v->mr[1], sizeof(*gpregs));
214
215   return tag;
216 }
217
218 L4_INLINE l4_msgtag_t
219 l4_vm_run_svm(l4_cap_idx_t task, l4_fpage_t vmcb_fpage,
220               struct l4_vm_svm_gpregs *gpregs) L4_NOTHROW
221 {
222   return l4_vm_run_svm_u(task, vmcb_fpage, gpregs, l4_utcb());
223 }