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_IRQ 0
183 #define SVM_INJECTION_NMI 2
184 #define SVM_INJECTION_EXCEPTION 3
185 #define SVM_INJECTION_SOFT_INTR 4
187 struct Interrupt_Info {
193 uint_t error_code : 32;
194 } __attribute__((packed));
198 struct VMCB_Control_Area {
200 struct Ctrl_Registers cr_reads;
201 struct Ctrl_Registers cr_writes;
202 struct Debug_Registers dr_reads;
203 struct Debug_Registers dr_writes;
204 struct Exception_Vectors exceptions;
205 struct Instr_Intercepts instrs;
206 struct SVM_Instr_Intercepts svm_instrs;
208 uchar_t rsvd1[44]; // Should be 0
211 ullong_t IOPM_BASE_PA;
212 ullong_t MSRPM_BASE_PA;
218 uchar_t rsvd2[3]; // Should be 0
220 struct Guest_Control guest_ctrl;
222 uint_t interrupt_shadow : 1;
223 uint_t rsvd3 : 31; // Should be 0
224 uint_t rsvd4; // Should be 0
230 /* This could be a typo in the manual....
231 * It doesn't actually say that there is a reserved bit
232 * But it does say that the EXITINTINFO field is in bits 63-1
233 * ALL other occurances mention a 1 bit reserved field
236 //ullong_t exit_int_info : 63;
239 // AMD Manual 2, pg 391, sect: 15.19
240 struct Interrupt_Info exit_int_info;
242 // uint_t NP_ENABLE : 1;
243 //ullong_t rsvd6 : 63; // Should be 0
246 uchar_t rsvd7[16]; // Should be 0
249 struct Interrupt_Info EVENTINJ;
252 /* This could be a typo in the manual....
253 * It doesn't actually say that there is a reserved bit
254 * But it does say that the EXITINTINFO field is in bits 63-1
255 * ALL other occurances mention a 1 bit reserved field
258 //ullong_t N_CR3 : 63;
263 uint_t LBR_VIRTUALIZATION_ENABLE : 1;
264 ullong_t rsvd9 : 63; // Should be 0
266 } __attribute__((packed));
269 typedef struct VMCB_Control_Area vmcb_ctrl_t;
276 struct vmcb_selector {
279 /* These attributes are basically a direct map of the attribute fields of a segment desc.
280 * The segment limit in the middle is removed and the fields are fused together
281 * There IS empty space at the end... See AMD Arch vol3, sect. 4.7.1, pg 78
286 uint_t type : 4; // segment type, [see Intel vol. 3b, sect. 3.4.5.1 (because I have the books)]
287 uint_t S : 1; // System=0, code/data=1
288 uint_t dpl : 2; // priviledge level, corresonds to protection ring
289 uint_t P : 1; // present flag
290 uint_t avl : 1; // available for use by system software
291 uint_t L : 1; // long mode (64 bit?)
292 uint_t db : 1; // default op size (0=16 bit seg, 1=32 bit seg)
293 uint_t G : 1; // Granularity, (0=bytes, 1=4k)
295 } __attribute__((packed)) fields;
296 } __attribute__((packed)) attrib;
300 } __attribute__((packed));
303 struct VMCB_State_Save_Area {
304 struct vmcb_selector es; // only lower 32 bits of base are implemented
305 struct vmcb_selector cs; // only lower 32 bits of base are implemented
306 struct vmcb_selector ss; // only lower 32 bits of base are implemented
307 struct vmcb_selector ds; // only lower 32 bits of base are implemented
308 struct vmcb_selector fs;
309 struct vmcb_selector gs;
311 struct vmcb_selector gdtr; // selector+attrib are reserved, only lower 16 bits of limit are implemented
312 struct vmcb_selector ldtr;
313 struct vmcb_selector idtr; // selector+attrib are reserved, only lower 16 bits of limit are implemented
314 struct vmcb_selector tr;
319 uchar_t cpl; // if the guest is real-mode then the CPL is forced to 0
320 // if the guest is virtual-mode then the CPL is forced to 3
351 ullong_t KernelGsBase;
352 ullong_t sysenter_cs;
353 ullong_t sysenter_esp;
354 ullong_t sysenter_eip;
361 ullong_t g_pat; // Guest PAT
362 // -- only used if nested paging is enabled
363 ullong_t dbgctl; // Guest DBGCTL MSR
364 // -- only used if the LBR registers are virtualized
365 ullong_t br_from; // Guest LastBranchFromIP MSR
366 // -- only used if the LBR registers are virtualized
367 ullong_t br_to; // Guest LastBranchToIP MSR
368 // -- only used if the LBR registers are virtualized
369 ullong_t lastexcpfrom; // Guest LastExceptionFromIP MSR
370 // -- only used if the LBR registers are virtualized
371 ullong_t lastexcpto; // Guest LastExceptionToIP MSR
372 // -- only used if the LBR registers are virtualized
374 } __attribute__((packed));
377 typedef struct VMCB_State_Save_Area vmcb_saved_state_t;
379 void PrintDebugVMCB(vmcb_t * vmcb);
382 void v3_set_vmcb_segments(vmcb_t * vmcb, struct v3_segments * segs);
383 void v3_get_vmcb_segments(vmcb_t * vmcb, struct v3_segments * segs);
385 #endif // ! __V3VEE__