4 * \brief X86 virtualization interface.
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.
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.
23 #include <l4/sys/ipc.h>
24 #include <l4/sys/task.h>
27 * \defgroup l4_vm_svm_api VM API for SVM
28 * \brief Virtual machine API for SVM.
34 * \brief VMCB structure for SVM VMs
35 * \ingroup l4_vm_svm_api
37 struct l4_vm_svm_vmcb_control_area
39 l4_uint16_t intercept_rd_crX;
40 l4_uint16_t intercept_wr_crX;
42 l4_uint16_t intercept_rd_drX;
43 l4_uint16_t intercept_wr_drX;
45 l4_uint32_t intercept_exceptions;
47 l4_uint32_t intercept_instruction0;
48 l4_uint32_t intercept_instruction1;
50 l4_uint8_t _reserved0[44];
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;
59 l4_uint64_t exitinfo1;
60 l4_uint64_t exitinfo2;
61 l4_uint64_t exitintinfo;
62 l4_uint64_t np_enable;
64 l4_uint8_t _reserved1[16];
68 l4_uint64_t lbr_virtualization_enable;
70 l4_uint8_t _reserved2[832];
71 } __attribute__((packed));
74 * \brief State save area segment selector struct
75 * \ingroup l4_vm_svm_api
77 struct l4_vm_svm_vmcb_state_save_area_seg
83 } __attribute__((packed));
86 * \brief State save area structure for SVM VMs
87 * \ingroup l4_vm_svm_api
89 struct l4_vm_svm_vmcb_state_save_area
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;
102 l4_uint8_t _reserved0[43];
106 l4_uint32_t _reserved1;
110 l4_uint8_t _reserved2[112];
120 l4_uint8_t _reserved3[88];
124 l4_uint8_t _reserved4[24];
131 l4_uint64_t kernelgsbase;
132 l4_uint64_t sysenter_cs;
133 l4_uint64_t sysenter_esp;
134 l4_uint64_t sysenter_eip;
137 l4_uint8_t _reserved5[32];
143 l4_uint64_t lastexcpfrom;
144 l4_uint64_t last_excpto;
146 l4_uint8_t _reserved6[2408];
147 } __attribute__((packed));
151 * \brief Control structure for SVM VMs
152 * \ingroup l4_vm_svm_api
154 struct l4_vm_svm_vmcb
156 struct l4_vm_svm_vmcb_control_area control_area;
157 struct l4_vm_svm_vmcb_state_save_area state_save_area;
162 * \ingroup l4_vm_svm_api
164 * \param vm Capability selector for VM
165 * \param vmcb_fpage VMCB
166 * \param gpregs General purpose registers
168 * \note SVM only for now
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;
176 * \ingroup l4_vm_svm_api
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;
185 * \brief Operations on task objects.
186 * \ingroup l4_vm_svm_api
190 L4_VM_RUN_OP = L4_TASK_VM_OPS + 0 /* Run a VM */
194 /****** Implementations ****************/
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
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;
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;
209 tag = l4_ipc_call(vm_task, u,
210 l4_msgtag(L4_PROTO_TASK, 1 + GPREGS_WORDS, 1, 0),
213 __builtin_memcpy(gpregs, &v->mr[1], sizeof(*gpregs));
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
222 return l4_vm_run_svm_u(task, vmcb_fpage, gpregs, l4_utcb());