2 * This file is part of the Palacios Virtual Machine Monitor developed
3 * by the V3VEE Project with funding from the United States National
4 * Science Foundation and the Department of Energy.
6 * The V3VEE Project is a joint project between Northwestern University
7 * and the University of New Mexico. You can find out more at
10 * Copyright (c) 2008, Jack Lange <jarusl@cs.northwestern.edu>
11 * Copyright (c) 2008, The V3VEE Project <http://www.v3vee.org>
12 * All rights reserved.
14 * Author: Jack Lange <jarusl@cs.northwestern.edu>
16 * This is free software. You are permitted to use,
17 * redistribute, and modify it as specified in the file "V3VEE_LICENSE".
25 #include <palacios/vmm_types.h>
26 #include <palacios/vm_guest.h>
28 #define VMCB_CTRL_AREA_OFFSET 0x0
29 #define VMCB_STATE_SAVE_AREA_OFFSET 0x400
32 #define GET_VMCB_CTRL_AREA(page) (page + VMCB_CTRL_AREA_OFFSET)
33 #define GET_VMCB_SAVE_STATE_AREA(page) (page + VMCB_STATE_SAVE_AREA_OFFSET)
40 struct Ctrl_Registers {
57 } __attribute__((packed));
60 struct Debug_Registers {
77 } __attribute__((packed));
80 struct Exception_Vectors {
81 uint_t de : 1; // (0) divide by zero
82 uint_t db : 1; // (1) Debug
83 uint_t nmi : 1; // (2) Non-maskable interrupt
84 uint_t bp : 1; // (3) Breakpoint
85 uint_t of : 1; // (4) Overflow
86 uint_t br : 1; // (5) Bound-Range
87 uint_t ud : 1; // (6) Invalid-Opcode
88 uint_t nm : 1; // (7) Device-not-available
89 uint_t df : 1; // (8) Double Fault
91 uint_t ts : 1; // (10) Invalid TSS
92 uint_t np : 1; // (11) Segment-not-present
93 uint_t ss : 1; // (12) Stack
94 uint_t gp : 1; // (13) General Protection Fault
95 uint_t pf : 1; // (14) Page fault
97 uint_t mf : 1; // (15) Floating point exception
98 uint_t ac : 1; // (16) Alignment-check
99 uint_t mc : 1; // (17) Machine Check
100 uint_t xf : 1; // (18) SIMD floating-point
111 uint_t sx : 1; // (30) Security Exception
113 } __attribute__((packed));
116 struct Instr_Intercepts {
144 uint_t IOIO_PROT : 1;
146 uint_t task_switch : 1;
147 uint_t FERR_FREEZE : 1;
148 uint_t shutdown_evts: 1;
149 } __attribute__((packed));
151 struct SVM_Instr_Intercepts {
163 uint_t MWAIT_always : 1;
164 uint_t MWAIT_if_armed : 1;
165 uint_t reserved : 19; // Should be 0
166 } __attribute__((packed));
169 struct Guest_Control {
172 uint_t rsvd1 : 7; // Should be 0
173 uint_t V_INTR_PRIO : 4;
174 uint_t V_IGN_TPR : 1;
175 uint_t rsvd2 : 3; // Should be 0
176 uint_t V_INTR_MASKING : 1;
177 uint_t rsvd3 : 7; // Should be 0
178 uchar_t V_INTR_VECTOR;
179 uint_t rsvd4 : 24; // Should be 0
180 } __attribute__((packed));
182 #define SVM_INJECTION_EXTERNAL_INTR 0
183 #define SVM_INJECTION_VIRTUAL_INTR 0
184 #define SVM_INJECTION_NMI 2
185 #define SVM_INJECTION_EXCEPTION 3
186 #define SVM_INJECTION_SOFT_INTR 4
188 struct Interrupt_Info {
194 uint_t error_code : 32;
195 } __attribute__((packed));
199 struct VMCB_Control_Area {
201 struct Ctrl_Registers cr_reads;
202 struct Ctrl_Registers cr_writes;
203 struct Debug_Registers dr_reads;
204 struct Debug_Registers dr_writes;
205 struct Exception_Vectors exceptions;
206 struct Instr_Intercepts instrs;
207 struct SVM_Instr_Intercepts svm_instrs;
209 uchar_t rsvd1[44]; // Should be 0
212 ullong_t IOPM_BASE_PA;
213 ullong_t MSRPM_BASE_PA;
219 uchar_t rsvd2[3]; // Should be 0
221 struct Guest_Control guest_ctrl;
223 uint_t interrupt_shadow : 1;
224 uint_t rsvd3 : 31; // Should be 0
225 uint_t rsvd4; // Should be 0
231 /* This could be a typo in the manual....
232 * It doesn't actually say that there is a reserved bit
233 * But it does say that the EXITINTINFO field is in bits 63-1
234 * ALL other occurances mention a 1 bit reserved field
237 //ullong_t exit_int_info : 63;
240 // AMD Manual 2, pg 391, sect: 15.19
241 struct Interrupt_Info exit_int_info;
243 // uint_t NP_ENABLE : 1;
244 //ullong_t rsvd6 : 63; // Should be 0
247 uchar_t rsvd7[16]; // Should be 0
250 struct Interrupt_Info EVENTINJ;
253 /* This could be a typo in the manual....
254 * It doesn't actually say that there is a reserved bit
255 * But it does say that the EXITINTINFO field is in bits 63-1
256 * ALL other occurances mention a 1 bit reserved field
259 //ullong_t N_CR3 : 63;
264 uint_t LBR_VIRTUALIZATION_ENABLE : 1;
265 ullong_t rsvd9 : 63; // Should be 0
267 } __attribute__((packed));
270 typedef struct VMCB_Control_Area vmcb_ctrl_t;
277 struct vmcb_selector {
280 /* These attributes are basically a direct map of the attribute fields of a segment desc.
281 * The segment limit in the middle is removed and the fields are fused together
282 * There IS empty space at the end... See AMD Arch vol3, sect. 4.7.1, pg 78
287 uint_t type : 4; // segment type, [see Intel vol. 3b, sect. 3.4.5.1 (because I have the books)]
288 uint_t S : 1; // System=0, code/data=1
289 uint_t dpl : 2; // priviledge level, corresonds to protection ring
290 uint_t P : 1; // present flag
291 uint_t avl : 1; // available for use by system software
292 uint_t L : 1; // long mode (64 bit?)
293 uint_t db : 1; // default op size (0=16 bit seg, 1=32 bit seg)
294 uint_t G : 1; // Granularity, (0=bytes, 1=4k)
296 } __attribute__((packed)) fields;
297 } __attribute__((packed)) attrib;
301 } __attribute__((packed));
304 struct VMCB_State_Save_Area {
305 struct vmcb_selector es; // only lower 32 bits of base are implemented
306 struct vmcb_selector cs; // only lower 32 bits of base are implemented
307 struct vmcb_selector ss; // only lower 32 bits of base are implemented
308 struct vmcb_selector ds; // only lower 32 bits of base are implemented
309 struct vmcb_selector fs;
310 struct vmcb_selector gs;
312 struct vmcb_selector gdtr; // selector+attrib are reserved, only lower 16 bits of limit are implemented
313 struct vmcb_selector ldtr;
314 struct vmcb_selector idtr; // selector+attrib are reserved, only lower 16 bits of limit are implemented
315 struct vmcb_selector tr;
320 uchar_t cpl; // if the guest is real-mode then the CPL is forced to 0
321 // if the guest is virtual-mode then the CPL is forced to 3
352 ullong_t KernelGsBase;
353 ullong_t sysenter_cs;
354 ullong_t sysenter_esp;
355 ullong_t sysenter_eip;
362 ullong_t g_pat; // Guest PAT
363 // -- only used if nested paging is enabled
364 ullong_t dbgctl; // Guest DBGCTL MSR
365 // -- only used if the LBR registers are virtualized
366 ullong_t br_from; // Guest LastBranchFromIP MSR
367 // -- only used if the LBR registers are virtualized
368 ullong_t br_to; // Guest LastBranchToIP MSR
369 // -- only used if the LBR registers are virtualized
370 ullong_t lastexcpfrom; // Guest LastExceptionFromIP MSR
371 // -- only used if the LBR registers are virtualized
372 ullong_t lastexcpto; // Guest LastExceptionToIP MSR
373 // -- only used if the LBR registers are virtualized
375 } __attribute__((packed));
378 typedef struct VMCB_State_Save_Area vmcb_saved_state_t;
380 void PrintDebugVMCB(vmcb_t * vmcb);
383 void v3_set_vmcb_segments(vmcb_t * vmcb, struct v3_segments * segs);
384 void v3_get_vmcb_segments(vmcb_t * vmcb, struct v3_segments * segs);
386 #endif // ! __V3VEE__