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)
39 #define PACKED __attribute__((packed))
46 struct Ctrl_Registers {
63 } __attribute__((packed));
66 struct Debug_Registers {
83 } __attribute__((packed));
86 struct Exception_Vectors {
87 uint_t de : 1; // (0) divide by zero
88 uint_t db : 1; // (1) Debug
89 uint_t nmi : 1; // (2) Non-maskable interrupt
90 uint_t bp : 1; // (3) Breakpoint
91 uint_t of : 1; // (4) Overflow
92 uint_t br : 1; // (5) Bound-Range
93 uint_t ud : 1; // (6) Invalid-Opcode
94 uint_t nm : 1; // (7) Device-not-available
95 uint_t df : 1; // (8) Double Fault
97 uint_t ts : 1; // (10) Invalid TSS
98 uint_t np : 1; // (11) Segment-not-present
99 uint_t ss : 1; // (12) Stack
100 uint_t gp : 1; // (13) General Protection Fault
101 uint_t pf : 1; // (14) Page fault
103 uint_t mf : 1; // (15) Floating point exception
104 uint_t ac : 1; // (16) Alignment-check
105 uint_t mc : 1; // (17) Machine Check
106 uint_t xf : 1; // (18) SIMD floating-point
117 uint_t sx : 1; // (30) Security Exception
119 } __attribute__((packed));
122 struct Instr_Intercepts {
150 uint_t IOIO_PROT : 1;
152 uint_t task_switch : 1;
153 uint_t FERR_FREEZE : 1;
154 uint_t shutdown_evts: 1;
155 } __attribute__((packed));
157 struct SVM_Instr_Intercepts {
169 uint_t MWAIT_always : 1;
170 uint_t MWAIT_if_armed : 1;
171 uint_t reserved : 19; // Should be 0
172 } __attribute__((packed));
175 struct Guest_Control {
178 uint_t rsvd1 : 7; // Should be 0
179 uint_t V_INTR_PRIO : 4;
180 uint_t V_IGN_TPR : 1;
181 uint_t rsvd2 : 3; // Should be 0
182 uint_t V_INTR_MASKING : 1;
183 uint_t rsvd3 : 7; // Should be 0
184 uchar_t V_INTR_VECTOR;
185 uint_t rsvd4 : 24; // Should be 0
186 } __attribute__((packed));
188 #define SVM_INJECTION_EXTERNAL_INTR 0
189 #define SVM_INJECTION_VIRTUAL_INTR 0
190 #define SVM_INJECTION_NMI 2
191 #define SVM_INJECTION_EXCEPTION 3
192 #define SVM_INJECTION_SOFT_INTR 4
194 struct Interrupt_Info {
200 uint_t error_code : 32;
201 } __attribute__((packed));
205 struct VMCB_Control_Area {
207 struct Ctrl_Registers cr_reads;
208 struct Ctrl_Registers cr_writes;
209 struct Debug_Registers dr_reads;
210 struct Debug_Registers dr_writes;
211 struct Exception_Vectors exceptions;
212 struct Instr_Intercepts instrs;
213 struct SVM_Instr_Intercepts svm_instrs;
215 uchar_t rsvd1[44]; // Should be 0
218 ullong_t IOPM_BASE_PA;
219 ullong_t MSRPM_BASE_PA;
225 uchar_t rsvd2[3]; // Should be 0
227 struct Guest_Control guest_ctrl;
229 uint_t interrupt_shadow : 1;
230 uint_t rsvd3 : 31; // Should be 0
231 uint_t rsvd4; // Should be 0
237 /* This could be a typo in the manual....
238 * It doesn't actually say that there is a reserved bit
239 * But it does say that the EXITINTINFO field is in bits 63-1
240 * ALL other occurances mention a 1 bit reserved field
243 //ullong_t exit_int_info : 63;
246 // AMD Manual 2, pg 391, sect: 15.19
247 struct Interrupt_Info exit_int_info;
249 // uint_t NP_ENABLE : 1;
250 //ullong_t rsvd6 : 63; // Should be 0
253 uchar_t rsvd7[16]; // Should be 0
256 struct Interrupt_Info EVENTINJ;
259 /* This could be a typo in the manual....
260 * It doesn't actually say that there is a reserved bit
261 * But it does say that the EXITINTINFO field is in bits 63-1
262 * ALL other occurances mention a 1 bit reserved field
265 //ullong_t N_CR3 : 63;
270 uint_t LBR_VIRTUALIZATION_ENABLE : 1;
271 ullong_t rsvd9 : 63; // Should be 0
273 } __attribute__((packed));
276 typedef struct VMCB_Control_Area vmcb_ctrl_t;
283 struct vmcb_selector {
286 /* These attributes are basically a direct map of the attribute fields of a segment desc.
287 * The segment limit in the middle is removed and the fields are fused together
288 * There IS empty space at the end... See AMD Arch vol3, sect. 4.7.1, pg 78
293 uint_t type : 4; // segment type, [see Intel vol. 3b, sect. 3.4.5.1 (because I have the books)]
294 uint_t S : 1; // System=0, code/data=1
295 uint_t dpl : 2; // priviledge level, corresonds to protection ring
296 uint_t P : 1; // present flag
297 uint_t avl : 1; // available for use by system software
298 uint_t L : 1; // long mode (64 bit?)
299 uint_t db : 1; // default op size (0=16 bit seg, 1=32 bit seg)
300 uint_t G : 1; // Granularity, (0=bytes, 1=4k)
302 } __attribute__((packed)) fields;
303 } __attribute__((packed)) attrib;
307 } __attribute__((packed));
310 struct VMCB_State_Save_Area {
311 struct vmcb_selector es; // only lower 32 bits of base are implemented
312 struct vmcb_selector cs; // only lower 32 bits of base are implemented
313 struct vmcb_selector ss; // only lower 32 bits of base are implemented
314 struct vmcb_selector ds; // only lower 32 bits of base are implemented
315 struct vmcb_selector fs;
316 struct vmcb_selector gs;
318 struct vmcb_selector gdtr; // selector+attrib are reserved, only lower 16 bits of limit are implemented
319 struct vmcb_selector ldtr;
320 struct vmcb_selector idtr; // selector+attrib are reserved, only lower 16 bits of limit are implemented
321 struct vmcb_selector tr;
326 uchar_t cpl; // if the guest is real-mode then the CPL is forced to 0
327 // if the guest is virtual-mode then the CPL is forced to 3
358 ullong_t KernelGsBase;
359 ullong_t sysenter_cs;
360 ullong_t sysenter_esp;
361 ullong_t sysenter_eip;
368 ullong_t g_pat; // Guest PAT
369 // -- only used if nested paging is enabled
370 ullong_t dbgctl; // Guest DBGCTL MSR
371 // -- only used if the LBR registers are virtualized
372 ullong_t br_from; // Guest LastBranchFromIP MSR
373 // -- only used if the LBR registers are virtualized
374 ullong_t br_to; // Guest LastBranchToIP MSR
375 // -- only used if the LBR registers are virtualized
376 ullong_t lastexcpfrom; // Guest LastExceptionFromIP MSR
377 // -- only used if the LBR registers are virtualized
378 ullong_t lastexcpto; // Guest LastExceptionToIP MSR
379 // -- only used if the LBR registers are virtualized
381 } __attribute__((packed));
384 typedef struct VMCB_State_Save_Area vmcb_saved_state_t;
386 void PrintDebugVMCB(vmcb_t * vmcb);
389 void set_vmcb_segments(vmcb_t * vmcb, struct v3_segments * segs);
390 void get_vmcb_segments(vmcb_t * vmcb, struct v3_segments * segs);
392 #endif // ! __V3VEE__