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_CTRL_AREA_SIZE 0x400
30 #define VMCB_STATE_SAVE_AREA_OFFSET 0x400
31 #define VMCB_STATE_SAVE_AREA_SIZE 0x298
32 #define VMCB_END_OFFSET (VMCB_CTRL_AREA_SIZE+VMCB_STATE_SAVE_AREA_SIZE)
33 #define VMCB_TOTAL_SIZE 0x1000
35 #define GET_VMCB_CTRL_AREA(page) (page + VMCB_CTRL_AREA_OFFSET)
36 #define GET_VMCB_SAVE_STATE_AREA(page) (page + VMCB_STATE_SAVE_AREA_OFFSET)
43 struct Ctrl_Registers {
60 } __attribute__((packed));
63 struct Debug_Registers {
80 } __attribute__((packed));
83 struct Exception_Vectors {
84 uint_t de : 1; // (0) divide by zero
85 uint_t db : 1; // (1) Debug
86 uint_t nmi : 1; // (2) Non-maskable interrupt
87 uint_t bp : 1; // (3) Breakpoint
88 uint_t of : 1; // (4) Overflow
89 uint_t br : 1; // (5) Bound-Range
90 uint_t ud : 1; // (6) Invalid-Opcode
91 uint_t nm : 1; // (7) Device-not-available
92 uint_t df : 1; // (8) Double Fault
94 uint_t ts : 1; // (10) Invalid TSS
95 uint_t np : 1; // (11) Segment-not-present
96 uint_t ss : 1; // (12) Stack
97 uint_t gp : 1; // (13) General Protection Fault
98 uint_t pf : 1; // (14) Page fault
100 uint_t mf : 1; // (15) Floating point exception
101 uint_t ac : 1; // (16) Alignment-check
102 uint_t mc : 1; // (17) Machine Check
103 uint_t xf : 1; // (18) SIMD floating-point
114 uint_t sx : 1; // (30) Security Exception
116 } __attribute__((packed));
119 struct Instr_Intercepts {
147 uint_t IOIO_PROT : 1;
149 uint_t task_switch : 1;
150 uint_t FERR_FREEZE : 1;
151 uint_t shutdown_evts: 1;
152 } __attribute__((packed));
154 struct SVM_Instr_Intercepts {
166 uint_t MWAIT_always : 1;
167 uint_t MWAIT_if_armed : 1;
169 uint_t reserved : 18; // Should be 0
170 } __attribute__((packed));
173 struct Guest_Control {
176 uint_t rsvd1 : 7; // Should be 0
177 uint_t V_INTR_PRIO : 4;
178 uint_t V_IGN_TPR : 1;
179 uint_t rsvd2 : 3; // Should be 0
180 uint_t V_INTR_MASKING : 1;
181 uint_t rsvd3 : 6; // Should be 0
182 uint_t AVIC_enable : 1;
183 uchar_t V_INTR_VECTOR;
184 uint_t rsvd4 : 24; // Should be 0
185 } __attribute__((packed));
187 #define SVM_INJECTION_IRQ 0
188 #define SVM_INJECTION_NMI 2
189 #define SVM_INJECTION_EXCEPTION 3
190 #define SVM_INJECTION_SOFT_INTR 4
192 struct Interrupt_Info {
198 uint_t error_code : 32;
199 } __attribute__((packed));
203 struct VMCB_Control_Area {
205 struct Ctrl_Registers cr_reads;
206 struct Ctrl_Registers cr_writes;
208 struct Debug_Registers dr_reads;
209 struct Debug_Registers dr_writes;
211 struct Exception_Vectors exceptions;
213 struct Instr_Intercepts instrs;
215 struct SVM_Instr_Intercepts svm_instrs;
218 uchar_t rsvd1[40]; // Should be 0
221 uint16_t pause_filter_threshold;
222 uint16_t pause_filter_count;
225 ullong_t IOPM_BASE_PA;
226 ullong_t MSRPM_BASE_PA;
233 uchar_t rsvd2[3]; // Should be 0
236 struct Guest_Control guest_ctrl;
239 uint_t interrupt_shadow : 1;
240 uint64_t rsvd3 : 63; // Should be 0
248 struct Interrupt_Info exit_int_info;
251 uint_t NP_ENABLE : 1;
255 uint64_t AVIC_APIC_BAR: 52;
259 uchar_t rsvd6[8]; // Should be 0
262 struct Interrupt_Info EVENTINJ;
268 uint_t LBR_VIRTUALIZATION_ENABLE : 1;
269 ullong_t rsvd7 : 63; // Should be 0
272 uint32_t clean_bits; // used for VMCB caching
279 // fetch of instruction
280 uint8_t num_ifetch_bytes;
281 uint8_t ifetch_bytes[15];
284 uint64_t AVIC_APIC_backing_page : 52; // page-aligned
291 uint64_t AVIC_logical_table : 52; // page-aligned
292 uint64_t rsvd11 : 12;
295 uint8_t AVIC_PHYSICAL_MAX_INDEX;
297 uint64_t AVIC_PHYSICAL_TABLE_PTR: 40; // page-aligned
300 // offset 0x100 space from here to 0x3ff should be zero
301 uint8_t rsvd_tail[VMCB_CTRL_AREA_SIZE-0x100];
303 } __attribute__((packed));
306 typedef struct VMCB_Control_Area vmcb_ctrl_t;
313 struct vmcb_selector {
316 /* These attributes are basically a direct map of the attribute fields of a segment desc.
317 * The segment limit in the middle is removed and the fields are fused together
318 * There IS empty space at the end... See AMD Arch vol3, sect. 4.7.1, pg 78
323 uint_t type : 4; // segment type, [see Intel vol. 3b, sect. 3.4.5.1 (because I have the books)]
324 uint_t S : 1; // System=0, code/data=1
325 uint_t dpl : 2; // priviledge level, corresonds to protection ring
326 uint_t P : 1; // present flag
327 uint_t avl : 1; // available for use by system software
328 uint_t L : 1; // long mode (64 bit?)
329 uint_t db : 1; // default op size (0=16 bit seg, 1=32 bit seg)
330 uint_t G : 1; // Granularity, (0=bytes, 1=4k)
332 } __attribute__((packed)) fields;
333 } __attribute__((packed)) attrib;
337 } __attribute__((packed));
340 struct VMCB_State_Save_Area {
341 struct vmcb_selector es; // only lower 32 bits of base are implemented
342 struct vmcb_selector cs; // only lower 32 bits of base are implemented
343 struct vmcb_selector ss; // only lower 32 bits of base are implemented
344 struct vmcb_selector ds; // only lower 32 bits of base are implemented
345 struct vmcb_selector fs;
346 struct vmcb_selector gs;
348 struct vmcb_selector gdtr; // selector+attrib are reserved, only lower 16 bits of limit are implemented
349 struct vmcb_selector ldtr;
350 struct vmcb_selector idtr; // selector+attrib are reserved, only lower 16 bits of limit are implemented
351 struct vmcb_selector tr;
356 uchar_t cpl; // if the guest is real-mode then the CPL is forced to 0
357 // if the guest is virtual-mode then the CPL is forced to 3
388 ullong_t KernelGsBase;
389 ullong_t sysenter_cs;
390 ullong_t sysenter_esp;
391 ullong_t sysenter_eip;
398 ullong_t g_pat; // Guest PAT
399 // -- only used if nested paging is enabled
400 ullong_t dbgctl; // Guest DBGCTL MSR
401 // -- only used if the LBR registers are virtualized
402 ullong_t br_from; // Guest LastBranchFromIP MSR
403 // -- only used if the LBR registers are virtualized
404 ullong_t br_to; // Guest LastBranchToIP MSR
405 // -- only used if the LBR registers are virtualized
406 ullong_t lastexcpfrom; // Guest LastExceptionFromIP MSR
407 // -- only used if the LBR registers are virtualized
408 ullong_t lastexcpto; // Guest LastExceptionToIP MSR
409 // -- only used if the LBR registers are virtualized
412 // Remainder to end of page is reserved and zero
413 } __attribute__((packed));
416 typedef struct VMCB_State_Save_Area vmcb_saved_state_t;
418 void PrintDebugVMCB(vmcb_t * vmcb);
421 void v3_set_vmcb_segments(vmcb_t * vmcb, struct v3_segments * segs);
422 void v3_get_vmcb_segments(vmcb_t * vmcb, struct v3_segments * segs);
424 #endif // ! __V3VEE__