debuggers.hg

view xen/include/asm-x86/hvm/vmx/vmcs.h @ 19942:c1541cc7e985

vmx: Add support for Pause-Loop Exiting

New NHM processors will support Pause-Loop Exiting by adding 2
VM-execution control fields:
PLE_Gap - upper bound on the amount of time between two successive
executions of PAUSE in a loop.
PLE_Window - upper bound on the amount of time a guest is allowed to
execute in a PAUSE loop

If the time, between this execution of PAUSE and previous one, exceeds
the PLE_Gap, processor consider this PAUSE belongs to a new loop.
Otherwise, processor determins the the total execution time of this
loop(since 1st PAUSE in this loop), and triggers a VM exit if total
time exceeds the PLE_Window.
* Refer SDM volume 3b section 21.6.13 & 22.1.3.

Pause-Loop Exiting can be used to detect Lock-Holder Preemption, where
one VP is sched-out after hold a spinlock, then other VPs for same
lock are sched-in to waste the CPU time.

Our tests indicate that most spinlocks are held for less than 2^12
cycles. Performance tests show that with 2X LP over-commitment we can
get +2% perf improvement for kernel build(Even more perf gain with
more LPs).

Signed-off-by: Zhai Edwin <edwin.zhai@intel.com>
author Keir Fraser <keir.fraser@citrix.com>
date Tue Jul 07 14:06:35 2009 +0100 (2009-07-07)
parents bf37a89269bf
children 2681155bcb8b
line source
1 /*
2 * vmcs.h: VMCS related definitions
3 * Copyright (c) 2004, Intel Corporation.
4 *
5 * This program is free software; you can redistribute it and/or modify it
6 * under the terms and conditions of the GNU General Public License,
7 * version 2, as published by the Free Software Foundation.
8 *
9 * This program is distributed in the hope it will be useful, but WITHOUT
10 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
11 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
12 * more details.
13 *
14 * You should have received a copy of the GNU General Public License along with
15 * this program; if not, write to the Free Software Foundation, Inc., 59 Temple
16 * Place - Suite 330, Boston, MA 02111-1307 USA.
17 *
18 */
19 #ifndef __ASM_X86_HVM_VMX_VMCS_H__
20 #define __ASM_X86_HVM_VMX_VMCS_H__
22 #include <asm/config.h>
23 #include <asm/hvm/io.h>
24 #include <asm/hvm/vmx/vpmu.h>
26 extern void start_vmx(void);
27 extern void vmcs_dump_vcpu(struct vcpu *v);
28 extern void setup_vmcs_dump(void);
29 extern int vmx_cpu_up(void);
30 extern void vmx_cpu_down(void);
32 struct vmcs_struct {
33 u32 vmcs_revision_id;
34 unsigned char data [0]; /* vmcs size is read from MSR */
35 };
37 struct vmx_msr_entry {
38 u32 index;
39 u32 mbz;
40 u64 data;
41 };
43 enum {
44 VMX_INDEX_MSR_LSTAR = 0,
45 VMX_INDEX_MSR_STAR,
46 VMX_INDEX_MSR_SYSCALL_MASK,
48 VMX_MSR_COUNT
49 };
51 struct vmx_msr_state {
52 unsigned long flags;
53 unsigned long msrs[VMX_MSR_COUNT];
54 };
56 #define EPT_DEFAULT_MT 6
57 #define EPT_DEFAULT_GAW 3
59 struct vmx_domain {
60 unsigned long apic_access_mfn;
61 unsigned long vpid_base;
62 union {
63 struct {
64 u64 etmt :3,
65 gaw :3,
66 rsvd :6,
67 asr :52;
68 };
69 u64 eptp;
70 } ept_control;
71 };
73 struct arch_vmx_struct {
74 /* Virtual address of VMCS. */
75 struct vmcs_struct *vmcs;
77 /* Protects remote usage of VMCS (VMPTRLD/VMCLEAR). */
78 spinlock_t vmcs_lock;
80 /*
81 * Activation and launch status of this VMCS.
82 * - Activated on a CPU by VMPTRLD. Deactivated by VMCLEAR.
83 * - Launched on active CPU by VMLAUNCH when current VMCS.
84 */
85 struct list_head active_list;
86 int active_cpu;
87 int launched;
89 /* Cache of cpu execution control. */
90 u32 exec_control;
91 u32 secondary_exec_control;
93 u16 vpid;
95 /* PMU */
96 struct vpmu_struct vpmu;
98 #ifdef __x86_64__
99 struct vmx_msr_state msr_state;
100 unsigned long shadow_gs;
101 unsigned long cstar;
102 #endif
104 unsigned long *msr_bitmap;
105 unsigned int msr_count;
106 struct vmx_msr_entry *msr_area;
107 unsigned int host_msr_count;
108 struct vmx_msr_entry *host_msr_area;
110 unsigned long host_cr0;
112 /* Is the guest in real mode? */
113 uint8_t vmx_realmode;
114 /* Are we emulating rather than VMENTERing? */
115 uint8_t vmx_emulate;
116 /* Bitmask of segments that we can't safely use in virtual 8086 mode */
117 uint16_t vm86_segment_mask;
118 /* Shadow CS, SS, DS, ES, FS, GS, TR while in virtual 8086 mode */
119 struct segment_register vm86_saved_seg[x86_seg_tr + 1];
120 /* Remember EFLAGS while in virtual 8086 mode */
121 uint32_t vm86_saved_eflags;
122 };
124 int vmx_create_vmcs(struct vcpu *v);
125 void vmx_destroy_vmcs(struct vcpu *v);
126 void vmx_vmcs_enter(struct vcpu *v);
127 void vmx_vmcs_exit(struct vcpu *v);
129 #define CPU_BASED_VIRTUAL_INTR_PENDING 0x00000004
130 #define CPU_BASED_USE_TSC_OFFSETING 0x00000008
131 #define CPU_BASED_HLT_EXITING 0x00000080
132 #define CPU_BASED_INVLPG_EXITING 0x00000200
133 #define CPU_BASED_MWAIT_EXITING 0x00000400
134 #define CPU_BASED_RDPMC_EXITING 0x00000800
135 #define CPU_BASED_RDTSC_EXITING 0x00001000
136 #define CPU_BASED_CR3_LOAD_EXITING 0x00008000
137 #define CPU_BASED_CR3_STORE_EXITING 0x00010000
138 #define CPU_BASED_CR8_LOAD_EXITING 0x00080000
139 #define CPU_BASED_CR8_STORE_EXITING 0x00100000
140 #define CPU_BASED_TPR_SHADOW 0x00200000
141 #define CPU_BASED_VIRTUAL_NMI_PENDING 0x00400000
142 #define CPU_BASED_MOV_DR_EXITING 0x00800000
143 #define CPU_BASED_UNCOND_IO_EXITING 0x01000000
144 #define CPU_BASED_ACTIVATE_IO_BITMAP 0x02000000
145 #define CPU_BASED_MONITOR_TRAP_FLAG 0x08000000
146 #define CPU_BASED_ACTIVATE_MSR_BITMAP 0x10000000
147 #define CPU_BASED_MONITOR_EXITING 0x20000000
148 #define CPU_BASED_PAUSE_EXITING 0x40000000
149 #define CPU_BASED_ACTIVATE_SECONDARY_CONTROLS 0x80000000
150 extern u32 vmx_cpu_based_exec_control;
152 #define PIN_BASED_EXT_INTR_MASK 0x00000001
153 #define PIN_BASED_NMI_EXITING 0x00000008
154 #define PIN_BASED_VIRTUAL_NMIS 0x00000020
155 extern u32 vmx_pin_based_exec_control;
157 #define VM_EXIT_IA32E_MODE 0x00000200
158 #define VM_EXIT_ACK_INTR_ON_EXIT 0x00008000
159 #define VM_EXIT_SAVE_GUEST_PAT 0x00040000
160 #define VM_EXIT_LOAD_HOST_PAT 0x00080000
161 extern u32 vmx_vmexit_control;
163 #define VM_ENTRY_IA32E_MODE 0x00000200
164 #define VM_ENTRY_SMM 0x00000400
165 #define VM_ENTRY_DEACT_DUAL_MONITOR 0x00000800
166 #define VM_ENTRY_LOAD_GUEST_PAT 0x00004000
167 extern u32 vmx_vmentry_control;
169 #define SECONDARY_EXEC_VIRTUALIZE_APIC_ACCESSES 0x00000001
170 #define SECONDARY_EXEC_ENABLE_EPT 0x00000002
171 #define SECONDARY_EXEC_ENABLE_VPID 0x00000020
172 #define SECONDARY_EXEC_WBINVD_EXITING 0x00000040
173 #define SECONDARY_EXEC_UNRESTRICTED_GUEST 0x00000080
174 #define SECONDARY_EXEC_PAUSE_LOOP_EXITING 0x00000400
175 extern u32 vmx_secondary_exec_control;
177 extern bool_t cpu_has_vmx_ins_outs_instr_info;
179 #define cpu_has_wbinvd_exiting \
180 (vmx_secondary_exec_control & SECONDARY_EXEC_WBINVD_EXITING)
181 #define cpu_has_vmx_virtualize_apic_accesses \
182 (vmx_secondary_exec_control & SECONDARY_EXEC_VIRTUALIZE_APIC_ACCESSES)
183 #define cpu_has_vmx_tpr_shadow \
184 (vmx_cpu_based_exec_control & CPU_BASED_TPR_SHADOW)
185 #define cpu_has_vmx_vnmi \
186 (vmx_pin_based_exec_control & PIN_BASED_VIRTUAL_NMIS)
187 #define cpu_has_vmx_msr_bitmap \
188 (vmx_cpu_based_exec_control & CPU_BASED_ACTIVATE_MSR_BITMAP)
189 #define cpu_has_vmx_secondary_exec_control \
190 (vmx_cpu_based_exec_control & CPU_BASED_ACTIVATE_SECONDARY_CONTROLS)
191 #define cpu_has_vmx_ept \
192 (vmx_secondary_exec_control & SECONDARY_EXEC_ENABLE_EPT)
193 #define cpu_has_vmx_vpid \
194 (vmx_secondary_exec_control & SECONDARY_EXEC_ENABLE_VPID)
195 #define cpu_has_monitor_trap_flag \
196 (vmx_cpu_based_exec_control & CPU_BASED_MONITOR_TRAP_FLAG)
197 #define cpu_has_vmx_pat \
198 (vmx_vmentry_control & VM_ENTRY_LOAD_GUEST_PAT)
199 #define cpu_has_vmx_unrestricted_guest \
200 (vmx_secondary_exec_control & SECONDARY_EXEC_UNRESTRICTED_GUEST)
201 #define vmx_unrestricted_guest(v) \
202 ((v)->arch.hvm_vmx.secondary_exec_control & \
203 SECONDARY_EXEC_UNRESTRICTED_GUEST)
204 #define cpu_has_vmx_ple \
205 (vmx_secondary_exec_control & SECONDARY_EXEC_PAUSE_LOOP_EXITING)
207 /* GUEST_INTERRUPTIBILITY_INFO flags. */
208 #define VMX_INTR_SHADOW_STI 0x00000001
209 #define VMX_INTR_SHADOW_MOV_SS 0x00000002
210 #define VMX_INTR_SHADOW_SMI 0x00000004
211 #define VMX_INTR_SHADOW_NMI 0x00000008
213 /* VMCS field encodings. */
214 enum vmcs_field {
215 VIRTUAL_PROCESSOR_ID = 0x00000000,
216 GUEST_ES_SELECTOR = 0x00000800,
217 GUEST_CS_SELECTOR = 0x00000802,
218 GUEST_SS_SELECTOR = 0x00000804,
219 GUEST_DS_SELECTOR = 0x00000806,
220 GUEST_FS_SELECTOR = 0x00000808,
221 GUEST_GS_SELECTOR = 0x0000080a,
222 GUEST_LDTR_SELECTOR = 0x0000080c,
223 GUEST_TR_SELECTOR = 0x0000080e,
224 HOST_ES_SELECTOR = 0x00000c00,
225 HOST_CS_SELECTOR = 0x00000c02,
226 HOST_SS_SELECTOR = 0x00000c04,
227 HOST_DS_SELECTOR = 0x00000c06,
228 HOST_FS_SELECTOR = 0x00000c08,
229 HOST_GS_SELECTOR = 0x00000c0a,
230 HOST_TR_SELECTOR = 0x00000c0c,
231 IO_BITMAP_A = 0x00002000,
232 IO_BITMAP_A_HIGH = 0x00002001,
233 IO_BITMAP_B = 0x00002002,
234 IO_BITMAP_B_HIGH = 0x00002003,
235 MSR_BITMAP = 0x00002004,
236 MSR_BITMAP_HIGH = 0x00002005,
237 VM_EXIT_MSR_STORE_ADDR = 0x00002006,
238 VM_EXIT_MSR_STORE_ADDR_HIGH = 0x00002007,
239 VM_EXIT_MSR_LOAD_ADDR = 0x00002008,
240 VM_EXIT_MSR_LOAD_ADDR_HIGH = 0x00002009,
241 VM_ENTRY_MSR_LOAD_ADDR = 0x0000200a,
242 VM_ENTRY_MSR_LOAD_ADDR_HIGH = 0x0000200b,
243 TSC_OFFSET = 0x00002010,
244 TSC_OFFSET_HIGH = 0x00002011,
245 VIRTUAL_APIC_PAGE_ADDR = 0x00002012,
246 VIRTUAL_APIC_PAGE_ADDR_HIGH = 0x00002013,
247 APIC_ACCESS_ADDR = 0x00002014,
248 APIC_ACCESS_ADDR_HIGH = 0x00002015,
249 EPT_POINTER = 0x0000201a,
250 EPT_POINTER_HIGH = 0x0000201b,
251 GUEST_PHYSICAL_ADDRESS = 0x00002400,
252 GUEST_PHYSICAL_ADDRESS_HIGH = 0x00002401,
253 VMCS_LINK_POINTER = 0x00002800,
254 VMCS_LINK_POINTER_HIGH = 0x00002801,
255 GUEST_IA32_DEBUGCTL = 0x00002802,
256 GUEST_IA32_DEBUGCTL_HIGH = 0x00002803,
257 GUEST_PAT = 0x00002804,
258 GUEST_PAT_HIGH = 0x00002805,
259 GUEST_PDPTR0 = 0x0000280a,
260 GUEST_PDPTR0_HIGH = 0x0000280b,
261 GUEST_PDPTR1 = 0x0000280c,
262 GUEST_PDPTR1_HIGH = 0x0000280d,
263 GUEST_PDPTR2 = 0x0000280e,
264 GUEST_PDPTR2_HIGH = 0x0000280f,
265 GUEST_PDPTR3 = 0x00002810,
266 GUEST_PDPTR3_HIGH = 0x00002811,
267 HOST_PAT = 0x00002c00,
268 HOST_PAT_HIGH = 0x00002c01,
269 PIN_BASED_VM_EXEC_CONTROL = 0x00004000,
270 CPU_BASED_VM_EXEC_CONTROL = 0x00004002,
271 EXCEPTION_BITMAP = 0x00004004,
272 PAGE_FAULT_ERROR_CODE_MASK = 0x00004006,
273 PAGE_FAULT_ERROR_CODE_MATCH = 0x00004008,
274 CR3_TARGET_COUNT = 0x0000400a,
275 VM_EXIT_CONTROLS = 0x0000400c,
276 VM_EXIT_MSR_STORE_COUNT = 0x0000400e,
277 VM_EXIT_MSR_LOAD_COUNT = 0x00004010,
278 VM_ENTRY_CONTROLS = 0x00004012,
279 VM_ENTRY_MSR_LOAD_COUNT = 0x00004014,
280 VM_ENTRY_INTR_INFO = 0x00004016,
281 VM_ENTRY_EXCEPTION_ERROR_CODE = 0x00004018,
282 VM_ENTRY_INSTRUCTION_LEN = 0x0000401a,
283 TPR_THRESHOLD = 0x0000401c,
284 SECONDARY_VM_EXEC_CONTROL = 0x0000401e,
285 PLE_GAP = 0x00004020,
286 PLE_WINDOW = 0x00004022,
287 VM_INSTRUCTION_ERROR = 0x00004400,
288 VM_EXIT_REASON = 0x00004402,
289 VM_EXIT_INTR_INFO = 0x00004404,
290 VM_EXIT_INTR_ERROR_CODE = 0x00004406,
291 IDT_VECTORING_INFO = 0x00004408,
292 IDT_VECTORING_ERROR_CODE = 0x0000440a,
293 VM_EXIT_INSTRUCTION_LEN = 0x0000440c,
294 VMX_INSTRUCTION_INFO = 0x0000440e,
295 GUEST_ES_LIMIT = 0x00004800,
296 GUEST_CS_LIMIT = 0x00004802,
297 GUEST_SS_LIMIT = 0x00004804,
298 GUEST_DS_LIMIT = 0x00004806,
299 GUEST_FS_LIMIT = 0x00004808,
300 GUEST_GS_LIMIT = 0x0000480a,
301 GUEST_LDTR_LIMIT = 0x0000480c,
302 GUEST_TR_LIMIT = 0x0000480e,
303 GUEST_GDTR_LIMIT = 0x00004810,
304 GUEST_IDTR_LIMIT = 0x00004812,
305 GUEST_ES_AR_BYTES = 0x00004814,
306 GUEST_CS_AR_BYTES = 0x00004816,
307 GUEST_SS_AR_BYTES = 0x00004818,
308 GUEST_DS_AR_BYTES = 0x0000481a,
309 GUEST_FS_AR_BYTES = 0x0000481c,
310 GUEST_GS_AR_BYTES = 0x0000481e,
311 GUEST_LDTR_AR_BYTES = 0x00004820,
312 GUEST_TR_AR_BYTES = 0x00004822,
313 GUEST_INTERRUPTIBILITY_INFO = 0x00004824,
314 GUEST_ACTIVITY_STATE = 0x00004826,
315 GUEST_SYSENTER_CS = 0x0000482A,
316 HOST_SYSENTER_CS = 0x00004c00,
317 CR0_GUEST_HOST_MASK = 0x00006000,
318 CR4_GUEST_HOST_MASK = 0x00006002,
319 CR0_READ_SHADOW = 0x00006004,
320 CR4_READ_SHADOW = 0x00006006,
321 CR3_TARGET_VALUE0 = 0x00006008,
322 CR3_TARGET_VALUE1 = 0x0000600a,
323 CR3_TARGET_VALUE2 = 0x0000600c,
324 CR3_TARGET_VALUE3 = 0x0000600e,
325 EXIT_QUALIFICATION = 0x00006400,
326 GUEST_LINEAR_ADDRESS = 0x0000640a,
327 GUEST_CR0 = 0x00006800,
328 GUEST_CR3 = 0x00006802,
329 GUEST_CR4 = 0x00006804,
330 GUEST_ES_BASE = 0x00006806,
331 GUEST_CS_BASE = 0x00006808,
332 GUEST_SS_BASE = 0x0000680a,
333 GUEST_DS_BASE = 0x0000680c,
334 GUEST_FS_BASE = 0x0000680e,
335 GUEST_GS_BASE = 0x00006810,
336 GUEST_LDTR_BASE = 0x00006812,
337 GUEST_TR_BASE = 0x00006814,
338 GUEST_GDTR_BASE = 0x00006816,
339 GUEST_IDTR_BASE = 0x00006818,
340 GUEST_DR7 = 0x0000681a,
341 GUEST_RSP = 0x0000681c,
342 GUEST_RIP = 0x0000681e,
343 GUEST_RFLAGS = 0x00006820,
344 GUEST_PENDING_DBG_EXCEPTIONS = 0x00006822,
345 GUEST_SYSENTER_ESP = 0x00006824,
346 GUEST_SYSENTER_EIP = 0x00006826,
347 HOST_CR0 = 0x00006c00,
348 HOST_CR3 = 0x00006c02,
349 HOST_CR4 = 0x00006c04,
350 HOST_FS_BASE = 0x00006c06,
351 HOST_GS_BASE = 0x00006c08,
352 HOST_TR_BASE = 0x00006c0a,
353 HOST_GDTR_BASE = 0x00006c0c,
354 HOST_IDTR_BASE = 0x00006c0e,
355 HOST_SYSENTER_ESP = 0x00006c10,
356 HOST_SYSENTER_EIP = 0x00006c12,
357 HOST_RSP = 0x00006c14,
358 HOST_RIP = 0x00006c16,
359 };
361 #define VMCS_VPID_WIDTH 16
363 void vmx_disable_intercept_for_msr(struct vcpu *v, u32 msr);
364 int vmx_read_guest_msr(u32 msr, u64 *val);
365 int vmx_write_guest_msr(u32 msr, u64 val);
366 int vmx_add_guest_msr(u32 msr);
367 int vmx_add_host_load_msr(u32 msr);
369 #endif /* ASM_X86_HVM_VMX_VMCS_H__ */
371 /*
372 * Local variables:
373 * mode: C
374 * c-set-style: "BSD"
375 * c-basic-offset: 4
376 * tab-width: 4
377 * indent-tabs-mode: nil
378 * End:
379 */