ia64/xen-unstable

view xen/arch/x86/hvm/svm/svm.c @ 9059:a2dce576313f

Removing hvm_safe_block() from the SVM hlt function avoids SVM guest problems.
This is a temporary solution.

Signed-off-by: Tom Woller <thomas.woller@amd.com>
author kaf24@firebug.cl.cam.ac.uk
date Tue Feb 28 10:11:33 2006 +0100 (2006-02-28)
parents b5bb9920bf48
children 985879d9d935
line source
1 /*
2 * svm.c: handling SVM architecture-related VM exits
3 * Copyright (c) 2004, Intel Corporation.
4 * Copyright (c) 2005, AMD Corporation.
5 *
6 * This program is free software; you can redistribute it and/or modify it
7 * under the terms and conditions of the GNU General Public License,
8 * version 2, as published by the Free Software Foundation.
9 *
10 * This program is distributed in the hope it will be useful, but WITHOUT
11 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
12 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
13 * more details.
14 *
15 * You should have received a copy of the GNU General Public License along with
16 * this program; if not, write to the Free Software Foundation, Inc., 59 Temple
17 * Place - Suite 330, Boston, MA 02111-1307 USA.
18 *
19 */
21 #include <xen/config.h>
22 #include <xen/init.h>
23 #include <xen/lib.h>
24 #include <xen/trace.h>
25 #include <xen/sched.h>
26 #include <xen/irq.h>
27 #include <xen/softirq.h>
28 #include <asm/current.h>
29 #include <asm/io.h>
30 #include <asm/shadow.h>
31 #include <asm/regs.h>
32 #include <asm/cpufeature.h>
33 #include <asm/processor.h>
34 #include <asm/types.h>
35 #include <asm/msr.h>
36 #include <asm/spinlock.h>
37 #include <asm/hvm/hvm.h>
38 #include <asm/hvm/support.h>
39 #include <asm/hvm/io.h>
40 #include <asm/hvm/svm/svm.h>
41 #include <asm/hvm/svm/vmcb.h>
42 #include <asm/hvm/svm/emulate.h>
43 #include <asm/hvm/svm/vmmcall.h>
44 #include <asm/hvm/svm/intr.h>
45 #include <asm/shadow.h>
46 #if CONFIG_PAGING_LEVELS >= 3
47 #include <asm/shadow_64.h>
48 #endif
49 #include <public/sched.h>
50 #include <public/hvm/ioreq.h>
52 #define SVM_EXTRA_DEBUG
54 #ifdef TRACE_BUFFER
55 static unsigned long trace_values[NR_CPUS][4];
56 #define TRACE_VMEXIT(index,value) trace_values[current->processor][index]=value
57 #else
58 #define TRACE_VMEXIT(index,value) ((void)0)
59 #endif
61 /* Useful define */
62 #define MAX_INST_SIZE 15
64 /*
65 * External functions, etc. We should move these to some suitable header file(s) */
67 extern void do_nmi(struct cpu_user_regs *, unsigned long);
68 extern int inst_copy_from_guest(unsigned char *buf, unsigned long guest_eip,
69 int inst_len);
70 extern asmlinkage void do_IRQ(struct cpu_user_regs *);
71 extern void send_pio_req(struct cpu_user_regs *regs, unsigned long port,
72 unsigned long count, int size, long value, int dir, int pvalid);
73 extern int svm_instrlen(struct cpu_user_regs *regs, int mode);
74 extern void svm_dump_inst(unsigned long eip);
75 extern int svm_dbg_on;
76 void svm_manual_event_injection32(struct vcpu *v, struct cpu_user_regs *regs,
77 int vector, int has_code);
78 void svm_dump_regs(const char *from, struct cpu_user_regs *regs);
80 static struct asid_pool ASIDpool[NR_CPUS];
82 /*
83 * Initializes the POOL of ASID used by the guests per core.
84 */
85 void asidpool_init( int core )
86 {
87 int i;
88 ASIDpool[core].asid_lock = SPIN_LOCK_UNLOCKED;
89 spin_lock(&ASIDpool[core].asid_lock);
90 /* Host ASID is always in use */
91 ASIDpool[core].asid[INITIAL_ASID] = ASID_INUSE;
92 for( i=1; i<ASID_MAX; i++ )
93 {
94 ASIDpool[core].asid[i] = ASID_AVAILABLE;
95 }
96 spin_unlock(&ASIDpool[core].asid_lock);
97 }
100 /* internal function to get the next available ASID */
101 static int asidpool_fetch_next( struct vmcb_struct *vmcb, int core )
102 {
103 int i;
104 for( i = 1; i < ASID_MAX; i++ )
105 {
106 if( ASIDpool[core].asid[i] == ASID_AVAILABLE )
107 {
108 vmcb->guest_asid = i;
109 ASIDpool[core].asid[i] = ASID_INUSE;
110 return i;
111 }
112 }
113 return -1;
114 }
117 /*
118 * This functions assigns on the passed VMCB, the next
119 * available ASID number. If none are available, the
120 * TLB flush flag is set, and all retireds ASID
121 * are made available.
122 *
123 * Returns: 1 -- sucess;
124 * 0 -- failure -- no more ASID numbers
125 * available.
126 */
127 int asidpool_assign_next( struct vmcb_struct *vmcb, int retire_current,
128 int oldcore, int newcore )
129 {
130 int i;
131 int res = 1;
132 static unsigned long cnt=0;
134 spin_lock(&ASIDpool[oldcore].asid_lock);
135 if( retire_current && vmcb->guest_asid ) {
136 ASIDpool[oldcore].asid[ vmcb->guest_asid & (ASID_MAX-1) ] = ASID_RETIRED;
137 }
138 spin_unlock(&ASIDpool[oldcore].asid_lock);
139 spin_lock(&ASIDpool[newcore].asid_lock);
140 if( asidpool_fetch_next( vmcb, newcore ) < 0 ) {
141 if (svm_dbg_on)
142 printk( "SVM: tlb(%ld)\n", cnt++ );
143 /* FLUSH the TLB and all retired slots are made available */
144 vmcb->tlb_control = 1;
145 for( i = 1; i < ASID_MAX; i++ ) {
146 if( ASIDpool[newcore].asid[i] == ASID_RETIRED ) {
147 ASIDpool[newcore].asid[i] = ASID_AVAILABLE;
148 }
149 }
150 /* Get the First slot available */
151 res = asidpool_fetch_next( vmcb, newcore ) > 0;
152 }
153 spin_unlock(&ASIDpool[newcore].asid_lock);
154 return res;
155 }
157 void asidpool_retire( struct vmcb_struct *vmcb, int core )
158 {
159 spin_lock(&ASIDpool[core].asid_lock);
160 if( vmcb->guest_asid ) {
161 ASIDpool[core].asid[ vmcb->guest_asid & (ASID_MAX-1) ] = ASID_RETIRED;
162 }
163 spin_unlock(&ASIDpool[core].asid_lock);
164 }
166 static inline void svm_inject_exception(struct vmcb_struct *vmcb,
167 int trap, int error_code)
168 {
169 eventinj_t event;
171 event.bytes = 0;
172 event.fields.v = 1;
173 event.fields.type = EVENTTYPE_EXCEPTION;
174 event.fields.vector = trap;
175 event.fields.ev = 1;
176 event.fields.errorcode = error_code;
178 ASSERT(vmcb->eventinj.fields.v == 0);
180 vmcb->eventinj = event;
181 }
183 void stop_svm(void)
184 {
185 u32 eax, edx;
187 /* We turn off the EFER_SVME bit. */
188 rdmsr(MSR_EFER, eax, edx);
189 eax &= ~EFER_SVME;
190 wrmsr(MSR_EFER, eax, edx);
192 printk("AMD SVM Extension is disabled.\n");
193 }
195 int svm_initialize_guest_resources(struct vcpu *v)
196 {
197 svm_final_setup_guest(v);
198 return 1;
199 }
201 int svm_relinquish_guest_resources(struct vcpu *v)
202 {
203 svm_relinquish_resources(v);
204 return 1;
205 }
207 void svm_store_cpu_guest_regs(struct vcpu *v, struct cpu_user_regs *regs)
208 {
209 struct vmcb_struct *vmcb = v->arch.hvm_svm.vmcb;
211 #if defined (__x86_64__)
212 regs->rip = vmcb->rip;
213 regs->rsp = vmcb->rsp;
214 regs->rflags = vmcb->rflags;
215 regs->cs = vmcb->cs.sel;
216 regs->ds = vmcb->ds.sel;
217 regs->es = vmcb->es.sel;
218 regs->ss = vmcb->ss.sel;
219 regs->gs = vmcb->gs.sel;
220 regs->fs = vmcb->fs.sel;
221 #elif defined (__i386__)
222 regs->eip = vmcb->rip;
223 regs->esp = vmcb->rsp;
224 regs->eflags = vmcb->rflags;
225 regs->cs = vmcb->cs.sel;
226 regs->ds = vmcb->ds.sel;
227 regs->es = vmcb->es.sel;
228 regs->ss = vmcb->ss.sel;
229 regs->gs = vmcb->gs.sel;
230 regs->fs = vmcb->fs.sel;
231 #endif
232 }
234 void svm_load_cpu_guest_regs(struct vcpu *v, struct cpu_user_regs *regs)
235 {
236 svm_load_cpu_user_regs(v, regs);
237 }
239 #ifdef __x86_64__
240 static struct svm_msr_state percpu_msr[NR_CPUS];
242 static u32 msr_data_index[VMX_MSR_COUNT] =
243 {
244 MSR_LSTAR, MSR_STAR, MSR_CSTAR,
245 MSR_SYSCALL_MASK, MSR_EFER,
246 };
248 void svm_save_segments(struct vcpu *v)
249 {
250 rdmsrl(MSR_SHADOW_GS_BASE, v->arch.hvm_svm.msr_content.shadow_gs);
251 }
253 /*
254 * To avoid MSR save/restore at every VM exit/entry time, we restore
255 * the x86_64 specific MSRs at domain switch time. Since those MSRs are
256 * are not modified once set for generic domains, we don't save them,
257 * but simply reset them to the values set at percpu_traps_init().
258 */
259 void svm_load_msrs(void)
260 {
261 struct svm_msr_state *host_state = &percpu_msr[smp_processor_id()];
262 int i;
264 while ( host_state->flags )
265 {
266 i = find_first_set_bit(host_state->flags);
267 wrmsrl(msr_data_index[i], host_state->msr_items[i]);
268 clear_bit(i, &host_state->flags);
269 }
270 }
272 static void svm_save_init_msrs(void)
273 {
274 struct svm_msr_state *host_state = &percpu_msr[smp_processor_id()];
275 int i;
277 for ( i = 0; i < SVM_MSR_COUNT; i++ )
278 rdmsrl(msr_data_index[i], host_state->msr_items[i]);
279 }
281 #define CASE_READ_MSR(address) \
282 case MSR_ ## address: \
283 msr_content = msr->msr_items[SVM_INDEX_MSR_ ## address]; \
284 break
286 #define CASE_WRITE_MSR(address) \
287 case MSR_ ## address: \
288 msr->msr_items[SVM_INDEX_MSR_ ## address] = msr_content; \
289 if (!test_bit(SVM_INDEX_MSR_ ## address, &msr->flags)) \
290 { \
291 set_bit(SVM_INDEX_MSR_ ## address, &msr->flags); \
292 } \
293 break
296 #define IS_CANO_ADDRESS(add) 1
298 static inline int long_mode_do_msr_read(struct cpu_user_regs *regs)
299 {
300 u64 msr_content = 0;
301 struct vcpu *vc = current;
302 struct svm_msr_state *msr = &vc->arch.hvm_svm.msr_content;
303 struct vmcb_struct *vmcb = vc->arch.hvm_svm.vmcb;
305 switch (regs->ecx)
306 {
307 case MSR_EFER:
308 msr_content = msr->msr_items[SVM_INDEX_MSR_EFER];
309 HVM_DBG_LOG(DBG_LEVEL_2, "EFER msr_content %llx\n",
310 (unsigned long long)msr_content);
312 if (test_bit(SVM_CPU_STATE_LME_ENABLED, &vc->arch.hvm_svm.cpu_state))
313 msr_content |= 1 << _EFER_LME;
315 if (SVM_LONG_GUEST(vc))
316 msr_content |= 1 << _EFER_LMA;
318 break;
320 case MSR_FS_BASE:
321 if (!(SVM_LONG_GUEST(vc)))
322 /* XXX should it be GP fault */
323 domain_crash_synchronous();
325 msr_content = vmcb->fs.base;
326 break;
328 case MSR_GS_BASE:
329 if (!(SVM_LONG_GUEST(vc)))
330 domain_crash_synchronous();
332 msr_content = vmcb->gs.base;
333 break;
335 case MSR_SHADOW_GS_BASE:
336 msr_content = msr->shadow_gs;
337 break;
339 CASE_READ_MSR(STAR);
340 CASE_READ_MSR(LSTAR);
341 CASE_READ_MSR(CSTAR);
342 CASE_READ_MSR(SYSCALL_MASK);
343 default:
344 return 0;
345 }
347 HVM_DBG_LOG(DBG_LEVEL_2, "mode_do_msr_read: msr_content: %lx\n",
348 msr_content);
350 regs->eax = msr_content & 0xffffffff;
351 regs->edx = msr_content >> 32;
352 return 1;
353 }
355 static inline int long_mode_do_msr_write(struct cpu_user_regs *regs)
356 {
357 u64 msr_content = regs->eax | ((u64)regs->edx << 32);
358 struct vcpu *vc = current;
359 struct svm_msr_state *msr = &vc->arch.hvm_svm.msr_content;
360 struct svm_msr_state *host_state = &percpu_msr[smp_processor_id()];
361 struct vmcb_struct *vmcb = vc->arch.hvm_svm.vmcb;
363 HVM_DBG_LOG(DBG_LEVEL_1, "mode_do_msr_write msr %lx msr_content %lx\n",
364 regs->ecx, msr_content);
366 switch (regs->ecx)
367 {
368 case MSR_EFER:
369 if ((msr_content & EFER_LME) ^ test_bit(SVM_CPU_STATE_LME_ENABLED,
370 &vc->arch.hvm_svm.cpu_state))
371 {
372 if (test_bit(SVM_CPU_STATE_PG_ENABLED, &vc->arch.hvm_svm.cpu_state)
373 || !test_bit(SVM_CPU_STATE_PAE_ENABLED,
374 &vc->arch.hvm_svm.cpu_state))
375 {
376 svm_inject_exception(vmcb, TRAP_gp_fault, 0);
377 }
378 }
380 if (msr_content & EFER_LME)
381 set_bit(SVM_CPU_STATE_LME_ENABLED, &vc->arch.hvm_svm.cpu_state);
383 /* No update for LME/LMA since it have no effect */
384 msr->msr_items[SVM_INDEX_MSR_EFER] = msr_content;
385 if (msr_content & ~(EFER_LME | EFER_LMA))
386 {
387 msr->msr_items[SVM_INDEX_MSR_EFER] = msr_content;
388 if (!test_bit(SVM_INDEX_MSR_EFER, &msr->flags))
389 {
390 rdmsrl(MSR_EFER, host_state->msr_items[SVM_INDEX_MSR_EFER]);
391 set_bit(SVM_INDEX_MSR_EFER, &host_state->flags);
392 set_bit(SVM_INDEX_MSR_EFER, &msr->flags);
393 wrmsrl(MSR_EFER, msr_content);
394 }
395 }
396 break;
398 case MSR_FS_BASE:
399 case MSR_GS_BASE:
400 if (!(SVM_LONG_GUEST(vc)))
401 domain_crash_synchronous();
403 if (!IS_CANO_ADDRESS(msr_content))
404 {
405 HVM_DBG_LOG(DBG_LEVEL_1, "Not cano address of msr write\n");
406 svm_inject_exception(vmcb, TRAP_gp_fault, 0);
407 }
409 if (regs->ecx == MSR_FS_BASE)
410 vmcb->fs.base = msr_content;
411 else
412 vmcb->gs.base = msr_content;
413 break;
415 case MSR_SHADOW_GS_BASE:
416 if (!(SVM_LONG_GUEST(vc)))
417 domain_crash_synchronous();
419 vc->arch.hvm_svm.msr_content.shadow_gs = msr_content;
420 wrmsrl(MSR_SHADOW_GS_BASE, msr_content);
421 break;
423 CASE_WRITE_MSR(STAR);
424 CASE_WRITE_MSR(LSTAR);
425 CASE_WRITE_MSR(CSTAR);
426 CASE_WRITE_MSR(SYSCALL_MASK);
427 default:
428 return 0;
429 }
430 return 1;
431 }
433 void
434 svm_restore_msrs(struct vcpu *v)
435 {
436 int i = 0;
437 struct svm_msr_state *guest_state;
438 struct svm_msr_state *host_state;
439 unsigned long guest_flags;
441 guest_state = &v->arch.hvm_svm.msr_content;;
442 host_state = &percpu_msr[smp_processor_id()];
444 wrmsrl(MSR_SHADOW_GS_BASE, guest_state->shadow_gs);
445 guest_flags = guest_state->flags;
446 if (!guest_flags)
447 return;
449 while (guest_flags){
450 i = find_first_set_bit(guest_flags);
452 HVM_DBG_LOG(DBG_LEVEL_2,
453 "restore guest's index %d msr %lx with %lx\n",
454 i, (unsigned long) msr_data_index[i], (unsigned long) guest_state->msr_items[i]);
455 set_bit(i, &host_state->flags);
456 wrmsrl(msr_data_index[i], guest_state->msr_items[i]);
457 clear_bit(i, &guest_flags);
458 }
459 }
460 #else
461 #define svm_save_init_msrs() ((void)0)
463 static inline int long_mode_do_msr_read(struct cpu_user_regs *regs)
464 {
465 return 0;
466 }
468 static inline int long_mode_do_msr_write(struct cpu_user_regs *regs)
469 {
470 return 0;
471 }
472 #endif
474 void svm_store_cpu_guest_ctrl_regs(struct vcpu *v, unsigned long crs[8])
475 {
476 struct vmcb_struct *vmcb = v->arch.hvm_svm.vmcb;
478 crs[0] = vmcb->cr0;
479 crs[3] = vmcb->cr3;
480 crs[4] = vmcb->cr4;
481 }
483 void svm_modify_guest_state(struct vcpu *v)
484 {
485 svm_modify_vmcb(v, &v->arch.guest_context.user_regs);
486 }
488 int svm_realmode(struct vcpu *v)
489 {
490 unsigned long cr0 = v->arch.hvm_svm.cpu_shadow_cr0;
491 unsigned long eflags = v->arch.hvm_svm.vmcb->rflags;
493 return (eflags & X86_EFLAGS_VM) || !(cr0 & X86_CR0_PE);
494 }
496 int svm_instruction_length(struct vcpu *v)
497 {
498 struct vmcb_struct *vmcb = v->arch.hvm_svm.vmcb;
499 unsigned long cr0 = vmcb->cr0, eflags = vmcb->rflags, mode;
501 mode = (eflags & X86_EFLAGS_VM) || !(cr0 & X86_CR0_PE) ? 2 : 4;
502 return svm_instrlen(guest_cpu_user_regs(), mode);
503 }
505 int start_svm(void)
506 {
507 u32 eax, ecx, edx;
509 /* Xen does not fill x86_capability words except 0. */
510 ecx = cpuid_ecx(0x80000001);
511 boot_cpu_data.x86_capability[5] = ecx;
513 if (!(test_bit(X86_FEATURE_SVME, &boot_cpu_data.x86_capability)))
514 return 0;
516 rdmsr(MSR_EFER, eax, edx);
517 eax |= EFER_SVME;
518 wrmsr(MSR_EFER, eax, edx);
519 asidpool_init(smp_processor_id());
520 printk("AMD SVM Extension is enabled for cpu %d.\n", smp_processor_id());
522 svm_save_init_msrs();
524 /* Setup HVM interfaces */
525 hvm_funcs.disable = stop_svm;
527 hvm_funcs.initialize_guest_resources = svm_initialize_guest_resources;
528 hvm_funcs.relinquish_guest_resources = svm_relinquish_guest_resources;
530 hvm_funcs.store_cpu_guest_regs = svm_store_cpu_guest_regs;
531 hvm_funcs.load_cpu_guest_regs = svm_load_cpu_guest_regs;
533 #ifdef __x86_64__
534 hvm_funcs.save_segments = svm_save_segments;
535 hvm_funcs.load_msrs = svm_load_msrs;
536 hvm_funcs.restore_msrs = svm_restore_msrs;
537 #endif
539 hvm_funcs.store_cpu_guest_ctrl_regs = svm_store_cpu_guest_ctrl_regs;
540 hvm_funcs.modify_guest_state = svm_modify_guest_state;
542 hvm_funcs.realmode = svm_realmode;
543 hvm_funcs.paging_enabled = svm_paging_enabled;
544 hvm_funcs.instruction_length = svm_instruction_length;
546 hvm_enabled = 1;
548 return 1;
549 }
551 int svm_dbg_on = 0;
553 static inline int svm_do_debugout(unsigned long exit_code)
554 {
555 int i;
557 static unsigned long counter = 0;
558 static unsigned long works[] =
559 {
560 VMEXIT_IOIO,
561 VMEXIT_HLT,
562 VMEXIT_CPUID,
563 VMEXIT_DR0_READ,
564 VMEXIT_DR1_READ,
565 VMEXIT_DR2_READ,
566 VMEXIT_DR3_READ,
567 VMEXIT_DR6_READ,
568 VMEXIT_DR7_READ,
569 VMEXIT_DR0_WRITE,
570 VMEXIT_DR1_WRITE,
571 VMEXIT_DR2_WRITE,
572 VMEXIT_DR3_WRITE,
573 VMEXIT_CR0_READ,
574 VMEXIT_CR0_WRITE,
575 VMEXIT_CR3_READ,
576 VMEXIT_CR4_READ,
577 VMEXIT_MSR,
578 VMEXIT_CR0_WRITE,
579 VMEXIT_CR3_WRITE,
580 VMEXIT_CR4_WRITE,
581 VMEXIT_EXCEPTION_PF,
582 VMEXIT_INTR,
583 VMEXIT_INVLPG,
584 VMEXIT_EXCEPTION_NM
585 };
588 #if 0
589 if (svm_dbg_on && exit_code != 0x7B)
590 return 1;
591 #endif
593 counter++;
595 #if 0
596 if ((exit_code == 0x4E
597 || exit_code == VMEXIT_CR0_READ
598 || exit_code == VMEXIT_CR0_WRITE)
599 && counter < 200000)
600 return 0;
602 if ((exit_code == 0x4E) && counter < 500000)
603 return 0;
604 #endif
606 for (i = 0; i < sizeof(works) / sizeof(works[0]); i++)
607 if (exit_code == works[i])
608 return 0;
610 return 1;
611 }
614 void save_svm_cpu_user_regs(struct vcpu *v, struct cpu_user_regs *ctxt)
615 {
616 struct vmcb_struct *vmcb = v->arch.hvm_svm.vmcb;
618 ASSERT(vmcb);
620 ctxt->eax = vmcb->rax;
621 ctxt->ss = vmcb->ss.sel;
622 ctxt->esp = vmcb->rsp;
623 ctxt->eflags = vmcb->rflags;
624 ctxt->cs = vmcb->cs.sel;
625 ctxt->eip = vmcb->rip;
627 ctxt->gs = vmcb->gs.sel;
628 ctxt->fs = vmcb->fs.sel;
629 ctxt->es = vmcb->es.sel;
630 ctxt->ds = vmcb->ds.sel;
631 }
633 #if defined (__x86_64__)
634 void svm_store_cpu_user_regs(struct cpu_user_regs *regs, struct vcpu *c )
635 {
636 }
637 #elif defined (__i386__)
638 void svm_store_cpu_user_regs(struct cpu_user_regs *regs, struct vcpu *v)
639 {
640 struct vmcb_struct *vmcb = v->arch.hvm_svm.vmcb;
642 regs->eip = vmcb->rip;
643 regs->esp = vmcb->rsp;
644 regs->eflags = vmcb->rflags;
645 regs->cs = vmcb->cs.sel;
646 regs->ds = vmcb->ds.sel;
647 regs->es = vmcb->es.sel;
648 regs->ss = vmcb->ss.sel;
649 }
650 #endif
652 /* XXX Use svm_load_cpu_guest_regs instead */
653 #if defined (__i386__)
654 void svm_load_cpu_user_regs(struct vcpu *v, struct cpu_user_regs *regs)
655 {
656 struct vmcb_struct *vmcb = v->arch.hvm_svm.vmcb;
657 u32 *intercepts = &v->arch.hvm_svm.vmcb->exception_intercepts;
659 /* Write the guest register value into VMCB */
660 vmcb->rax = regs->eax;
661 vmcb->ss.sel = regs->ss;
662 vmcb->rsp = regs->esp;
663 vmcb->rflags = regs->eflags;
664 vmcb->cs.sel = regs->cs;
665 vmcb->rip = regs->eip;
666 if (regs->eflags & EF_TF)
667 *intercepts |= EXCEPTION_BITMAP_DB;
668 else
669 *intercepts &= ~EXCEPTION_BITMAP_DB;
670 }
671 #else /* (__i386__) */
672 void svm_load_cpu_user_regs(struct vcpu *v, struct cpu_user_regs *regs)
673 {
674 struct vmcb_struct *vmcb = v->arch.hvm_svm.vmcb;
675 u32 *intercepts = &v->arch.hvm_svm.vmcb->exception_intercepts;
677 /* Write the guest register value into VMCB */
678 vmcb->rax = regs->rax;
679 vmcb->ss.sel = regs->ss;
680 vmcb->rsp = regs->rsp;
681 vmcb->rflags = regs->rflags;
682 vmcb->cs.sel = regs->cs;
683 vmcb->rip = regs->rip;
684 if (regs->rflags & EF_TF)
685 *intercepts |= EXCEPTION_BITMAP_DB;
686 else
687 *intercepts &= ~EXCEPTION_BITMAP_DB;
688 }
689 #endif /* !(__i386__) */
691 int svm_paging_enabled(struct vcpu *v)
692 {
693 unsigned long cr0;
695 cr0 = v->arch.hvm_svm.cpu_shadow_cr0;
697 return (cr0 & X86_CR0_PE) && (cr0 & X86_CR0_PG);
698 }
701 /* Make sure that xen intercepts any FP accesses from current */
702 void svm_stts(struct vcpu *v)
703 {
704 struct vmcb_struct *vmcb = v->arch.hvm_svm.vmcb;
706 /* FPU state already dirty? Then no need to setup_fpu() lazily. */
707 if ( test_bit(_VCPUF_fpu_dirtied, &v->vcpu_flags) )
708 return;
710 /*
711 * If the guest does not have TS enabled then we must cause and handle an
712 * exception on first use of the FPU. If the guest *does* have TS enabled
713 * then this is not necessary: no FPU activity can occur until the guest
714 * clears CR0.TS, and we will initialise the FPU when that happens.
715 */
716 if ( !(v->arch.hvm_svm.cpu_shadow_cr0 & X86_CR0_TS) )
717 {
718 v->arch.hvm_svm.vmcb->exception_intercepts |= EXCEPTION_BITMAP_NM;
719 vmcb->cr0 |= X86_CR0_TS;
720 }
721 }
723 static void arch_svm_do_launch(struct vcpu *v)
724 {
725 cpu_user_regs_t *regs = &current->arch.guest_context.user_regs;
726 int error;
728 #if 0
729 if (svm_dbg_on)
730 printk("Do launch\n");
731 #endif
732 error = construct_vmcb(&v->arch.hvm_svm, regs);
733 if ( error < 0 )
734 {
735 if (v->vcpu_id == 0) {
736 printk("Failed to construct a new VMCB for BSP.\n");
737 } else {
738 printk("Failed to construct a new VMCB for AP %d\n", v->vcpu_id);
739 }
740 domain_crash_synchronous();
741 }
743 svm_do_launch(v);
744 #if 0
745 if (svm_dbg_on)
746 svm_dump_host_regs(__func__);
747 #endif
748 reset_stack_and_jump(svm_asm_do_launch);
749 }
751 void svm_final_setup_guest(struct vcpu *v)
752 {
753 v->arch.schedule_tail = arch_svm_do_launch;
755 if (v == v->domain->vcpu[0])
756 {
757 struct domain *d = v->domain;
758 struct vcpu *vc;
760 /* Initialize monitor page table */
761 for_each_vcpu(d, vc)
762 vc->arch.monitor_table = mk_pagetable(0);
764 /*
765 * Required to do this once per domain
766 * TODO: add a seperate function to do these.
767 */
768 memset(&d->shared_info->evtchn_mask[0], 0xff,
769 sizeof(d->shared_info->evtchn_mask));
771 /*
772 * Put the domain in shadow mode even though we're going to be using
773 * the shared 1:1 page table initially. It shouldn't hurt
774 */
775 shadow_mode_enable(d,
776 SHM_enable|SHM_refcounts|
777 SHM_translate|SHM_external|SHM_wr_pt_pte);
778 }
779 }
782 void svm_relinquish_resources(struct vcpu *v)
783 {
784 struct hvm_virpit *vpit;
785 extern void destroy_vmcb(struct arch_svm_struct *); /* XXX */
787 #if 0
788 /*
789 * This is not stored at the moment. We need to keep it somewhere and free
790 * it Or maybe not, as it's a per-cpu-core item, and I guess we don't
791 * normally remove CPU's other than for hot-plug capable systems, where I
792 * guess we have to allocate and free host-save area in this case. Let's
793 * not worry about it at the moment, as loosing one page per CPU hot-plug
794 * event doesn't seem that excessive. But I may be wrong.
795 */
796 free_host_save_area(v->arch.hvm_svm.host_save_area);
797 #endif
799 if ( v->vcpu_id == 0 )
800 {
801 /* unmap IO shared page */
802 struct domain *d = v->domain;
803 if ( d->arch.hvm_domain.shared_page_va )
804 unmap_domain_page((void *)d->arch.hvm_domain.shared_page_va);
805 shadow_direct_map_clean(d);
806 }
808 destroy_vmcb(&v->arch.hvm_svm);
809 free_monitor_pagetable(v);
810 vpit = &v->domain->arch.hvm_domain.vpit;
811 kill_timer(&vpit->pit_timer);
812 kill_timer(&v->arch.hvm_svm.hlt_timer);
813 if ( hvm_apic_support(v->domain) ) {
814 kill_timer( &(VLAPIC(v)->vlapic_timer) );
815 xfree( VLAPIC(v) );
816 }
817 }
820 void arch_svm_do_resume(struct vcpu *v)
821 {
822 svm_do_resume(v);
823 reset_stack_and_jump(svm_asm_do_resume);
824 }
827 static int svm_do_page_fault(unsigned long va, struct cpu_user_regs *regs)
828 {
829 struct vcpu *v = current;
830 unsigned long eip;
831 unsigned long gpa; /* FIXME: PAE */
832 int result;
833 struct vmcb_struct *vmcb = v->arch.hvm_svm.vmcb;
835 ASSERT(vmcb);
837 //#if HVM_DEBUG
838 eip = vmcb->rip;
839 HVM_DBG_LOG(DBG_LEVEL_VMMU,
840 "svm_do_page_fault = 0x%lx, eip = %lx, error_code = %lx",
841 va, eip, (unsigned long)regs->error_code);
842 //#endif
844 if ( !svm_paging_enabled(v) )
845 {
846 if ( shadow_direct_map_fault(va, regs) )
847 return 1;
849 handle_mmio(va, va);
850 TRACE_VMEXIT(2,2);
851 return 1;
852 }
855 gpa = gva_to_gpa(va);
857 /* Use 1:1 page table to identify MMIO address space */
858 if (mmio_space(gpa))
859 {
860 /* No support for APIC */
861 if (!hvm_apic_support(v->domain) && gpa >= 0xFEC00000)
862 {
863 unsigned long inst_len;
864 inst_len = svm_instruction_length(v);
865 if (inst_len == (unsigned long)-1)
866 {
867 printf("%s: INST_LEN - Unable to decode properly.\n", __func__);
868 domain_crash_synchronous();
869 }
871 __update_guest_eip(vmcb, inst_len);
873 return 1;
874 }
876 TRACE_VMEXIT (2,2);
877 handle_mmio(va, gpa);
879 return 1;
880 }
882 result = shadow_fault(va, regs);
884 if( result ) {
885 /* Let's make sure that the Guest TLB is flushed */
886 set_bit(ARCH_SVM_VMCB_ASSIGN_ASID, &v->arch.hvm_svm.flags);
887 }
889 TRACE_VMEXIT (2,result);
891 return result;
892 }
895 static void svm_do_no_device_fault(struct vmcb_struct *vmcb)
896 {
897 struct vcpu *v = current;
899 setup_fpu(v);
900 vmcb->exception_intercepts &= ~EXCEPTION_BITMAP_NM;
902 if ( !(v->arch.hvm_svm.cpu_shadow_cr0 & X86_CR0_TS) )
903 vmcb->cr0 &= ~X86_CR0_TS;
904 }
907 static void svm_do_general_protection_fault(struct vcpu *v,
908 struct cpu_user_regs *regs)
909 {
910 struct vmcb_struct *vmcb = v->arch.hvm_svm.vmcb;
911 unsigned long eip, error_code;
913 ASSERT(vmcb);
915 eip = vmcb->rip;
916 error_code = vmcb->exitinfo1;
918 HVM_DBG_LOG(DBG_LEVEL_1,
919 "svm_general_protection_fault: eip = %lx, erro_code = %lx",
920 eip, error_code);
922 HVM_DBG_LOG(DBG_LEVEL_1,
923 "eax=%lx, ebx=%lx, ecx=%lx, edx=%lx, esi=%lx, edi=%lx",
924 (unsigned long)regs->eax, (unsigned long)regs->ebx,
925 (unsigned long)regs->ecx, (unsigned long)regs->edx,
926 (unsigned long)regs->esi, (unsigned long)regs->edi);
929 /* Reflect it back into the guest */
930 svm_inject_exception(vmcb, TRAP_gp_fault, error_code);
931 }
933 /* Reserved bits: [31:14], [12:1] */
934 #define SVM_VCPU_CPUID_L1_RESERVED 0xffffdffe
936 static void svm_vmexit_do_cpuid(struct vmcb_struct *vmcb, unsigned long input,
937 struct cpu_user_regs *regs)
938 {
939 unsigned int eax, ebx, ecx, edx;
940 unsigned long eip;
941 struct vcpu *v = current;
942 unsigned int inst_len;
944 ASSERT(vmcb);
946 eip = vmcb->rip;
948 HVM_DBG_LOG(DBG_LEVEL_1,
949 "do_cpuid: (eax) %lx, (ebx) %lx, (ecx) %lx, (edx) %lx,"
950 " (esi) %lx, (edi) %lx",
951 (unsigned long)regs->eax, (unsigned long)regs->ebx,
952 (unsigned long)regs->ecx, (unsigned long)regs->edx,
953 (unsigned long)regs->esi, (unsigned long)regs->edi);
955 cpuid(input, &eax, &ebx, &ecx, &edx);
957 if (input == 1)
958 {
959 if ( hvm_apic_support(v->domain) &&
960 !vlapic_global_enabled((VLAPIC(v))) )
961 clear_bit(X86_FEATURE_APIC, &edx);
963 #ifdef __x86_64__
964 if ( v->domain->arch.ops->guest_paging_levels == PAGING_L2 )
965 #endif
966 {
967 clear_bit(X86_FEATURE_PSE, &edx);
968 clear_bit(X86_FEATURE_PAE, &edx);
969 clear_bit(X86_FEATURE_PSE36, &edx);
970 }
972 /* Clear out reserved bits. */
973 ecx &= ~SVM_VCPU_CPUID_L1_RESERVED; /* mask off reserved bits */
974 }
975 #ifdef __i386__
976 else if ( input == 0x80000001 )
977 {
978 /* Mask feature for Intel ia32e or AMD long mode. */
979 clear_bit(X86_FEATURE_LM & 31, &edx);
980 }
981 #endif
983 regs->eax = (unsigned long)eax;
984 regs->ebx = (unsigned long)ebx;
985 regs->ecx = (unsigned long)ecx;
986 regs->edx = (unsigned long)edx;
988 HVM_DBG_LOG(DBG_LEVEL_1,
989 "svm_vmexit_do_cpuid: eip: %lx, input: %lx, out:eax=%x, "
990 "ebx=%x, ecx=%x, edx=%x",
991 eip, input, eax, ebx, ecx, edx);
993 inst_len = __get_instruction_length(vmcb, INSTR_CPUID, NULL);
994 __update_guest_eip(vmcb, inst_len);
995 }
998 static inline unsigned long *get_reg_p(unsigned int gpreg,
999 struct cpu_user_regs *regs, struct vmcb_struct *vmcb)
1001 unsigned long *reg_p = NULL;
1002 switch (gpreg)
1004 case SVM_REG_EAX:
1005 reg_p = (unsigned long *)&regs->eax;
1006 break;
1007 case SVM_REG_EBX:
1008 reg_p = (unsigned long *)&regs->ebx;
1009 break;
1010 case SVM_REG_ECX:
1011 reg_p = (unsigned long *)&regs->ecx;
1012 break;
1013 case SVM_REG_EDX:
1014 reg_p = (unsigned long *)&regs->edx;
1015 break;
1016 case SVM_REG_EDI:
1017 reg_p = (unsigned long *)&regs->edi;
1018 break;
1019 case SVM_REG_ESI:
1020 reg_p = (unsigned long *)&regs->esi;
1021 break;
1022 case SVM_REG_EBP:
1023 reg_p = (unsigned long *)&regs->ebp;
1024 break;
1025 case SVM_REG_ESP:
1026 reg_p = (unsigned long *)&vmcb->rsp;
1027 break;
1028 #if __x86_64__
1029 case SVM_REG_R8:
1030 reg_p = (unsigned long *)&regs->r8;
1031 break;
1032 case SVM_REG_R9:
1033 reg_p = (unsigned long *)&regs->r9;
1034 break;
1035 case SVM_REG_R10:
1036 reg_p = (unsigned long *)&regs->r10;
1037 break;
1038 case SVM_REG_R11:
1039 reg_p = (unsigned long *)&regs->r11;
1040 break;
1041 case SVM_REG_R12:
1042 reg_p = (unsigned long *)&regs->r12;
1043 break;
1044 case SVM_REG_R13:
1045 reg_p = (unsigned long *)&regs->r13;
1046 break;
1047 case SVM_REG_R14:
1048 reg_p = (unsigned long *)&regs->r14;
1049 break;
1050 case SVM_REG_R15:
1051 reg_p = (unsigned long *)&regs->r15;
1052 break;
1053 #endif
1054 default:
1055 BUG();
1058 return reg_p;
1062 static inline unsigned long get_reg(unsigned int gpreg,
1063 struct cpu_user_regs *regs, struct vmcb_struct *vmcb)
1065 unsigned long *gp;
1066 gp = get_reg_p(gpreg, regs, vmcb);
1067 return *gp;
1071 static inline void set_reg(unsigned int gpreg, unsigned long value,
1072 struct cpu_user_regs *regs, struct vmcb_struct *vmcb)
1074 unsigned long *gp;
1075 gp = get_reg_p(gpreg, regs, vmcb);
1076 *gp = value;
1080 static void svm_dr_access (struct vcpu *v, unsigned int reg, unsigned int type,
1081 struct cpu_user_regs *regs)
1083 unsigned long *reg_p = 0;
1084 unsigned int gpreg = 0;
1085 unsigned long eip;
1086 unsigned int inst_len;
1087 struct vmcb_struct *vmcb;
1088 u8 buffer[MAX_INST_LEN];
1090 vmcb = v->arch.hvm_svm.vmcb;
1092 ASSERT(vmcb);
1094 eip = vmcb->rip;
1095 inst_copy_from_guest(buffer, svm_rip2pointer(vmcb), sizeof(buffer));
1097 ASSERT(buffer[0] == 0x0f && (buffer[1] & 0xFD) == 0x21);
1099 gpreg = decode_src_reg(buffer[2]);
1100 #if DEBUG
1101 ASSERT(reg == decode_dest_reg(buffer[2]));
1102 #endif
1104 HVM_DBG_LOG(DBG_LEVEL_1, "svm_dr_access : eip=%lx, reg=%d, gpreg = %x",
1105 eip, reg, gpreg);
1107 reg_p = get_reg_p(gpreg, regs, vmcb);
1109 switch (type)
1111 case TYPE_MOV_TO_DR:
1112 inst_len = __get_instruction_length(vmcb, INSTR_MOV2DR, buffer);
1113 v->arch.guest_context.debugreg[reg] = *reg_p;
1114 break;
1115 case TYPE_MOV_FROM_DR:
1116 inst_len = __get_instruction_length(vmcb, INSTR_MOVDR2, buffer);
1117 *reg_p = v->arch.guest_context.debugreg[reg];
1118 break;
1119 default:
1120 __hvm_bug(regs);
1121 break;
1123 __update_guest_eip(vmcb, inst_len);
1127 static unsigned int check_for_null_selector(struct vmcb_struct *vmcb,
1128 unsigned int dir, unsigned long *base, unsigned int real)
1131 unsigned char inst[MAX_INST_LEN];
1132 segment_selector_t seg;
1133 int i;
1135 memset(inst, 0, MAX_INST_LEN);
1136 if (inst_copy_from_guest(inst, svm_rip2pointer(vmcb), sizeof(inst))
1137 != MAX_INST_LEN)
1139 printk("check_for_null_selector: get guest instruction failed\n");
1140 domain_crash_synchronous();
1143 for (i = 0; i < MAX_INST_LEN; i++)
1145 switch (inst[i])
1147 case 0xf3: /* REPZ */
1148 case 0xf2: /* REPNZ */
1149 case 0xf0: /* LOCK */
1150 case 0x66: /* data32 */
1151 case 0x67: /* addr32 */
1152 #if __x86_64__
1153 /* REX prefixes */
1154 case 0x40:
1155 case 0x41:
1156 case 0x42:
1157 case 0x43:
1158 case 0x44:
1159 case 0x45:
1160 case 0x46:
1161 case 0x47:
1163 case 0x48:
1164 case 0x49:
1165 case 0x4a:
1166 case 0x4b:
1167 case 0x4c:
1168 case 0x4d:
1169 case 0x4e:
1170 case 0x4f:
1171 #endif
1172 continue;
1173 case 0x2e: /* CS */
1174 seg = vmcb->cs;
1175 break;
1176 case 0x36: /* SS */
1177 seg = vmcb->ss;
1178 break;
1179 case 0x26: /* ES */
1180 seg = vmcb->es;
1181 break;
1182 case 0x64: /* FS */
1183 seg = vmcb->fs;
1184 break;
1185 case 0x65: /* GS */
1186 seg = vmcb->gs;
1187 break;
1188 case 0x3e: /* DS */
1189 /* FALLTHROUGH */
1190 seg = vmcb->ds;
1191 break;
1192 default:
1193 if (dir == IOREQ_READ)
1194 seg = vmcb->es;
1195 else
1196 seg = vmcb->ds;
1199 /* In real Mode */
1200 if (real)
1201 seg.base = seg.sel << 4;
1203 if (base)
1204 *base = seg.base;
1206 return seg.attributes.fields.p;
1209 ASSERT(0);
1210 return 0;
1214 /* Get the address of INS/OUTS instruction */
1215 static inline unsigned long svm_get_io_address(struct vmcb_struct *vmcb,
1216 struct cpu_user_regs *regs, unsigned int dir, unsigned int real)
1218 unsigned long addr = 0;
1219 unsigned long base = 0;
1221 check_for_null_selector(vmcb, dir, &base, real);
1223 if (dir == IOREQ_WRITE)
1225 if (real)
1226 addr = (regs->esi & 0xFFFF) + base;
1227 else
1228 addr = regs->esi + base;
1230 else
1232 if (real)
1233 addr = (regs->edi & 0xFFFF) + base;
1234 else
1235 addr = regs->edi + base;
1238 return addr;
1242 static void svm_io_instruction(struct vcpu *v, struct cpu_user_regs *regs)
1244 struct mmio_op *mmio_opp;
1245 unsigned long eip, cs, eflags, cr0;
1246 unsigned long port;
1247 unsigned int real, size, dir;
1248 ioio_info_t info;
1250 struct vmcb_struct *vmcb = v->arch.hvm_svm.vmcb;
1252 ASSERT(vmcb);
1253 mmio_opp = &current->arch.hvm_vcpu.mmio_op;
1254 mmio_opp->instr = INSTR_PIO;
1255 mmio_opp->flags = 0;
1257 eip = vmcb->rip;
1258 cs = vmcb->cs.sel;
1259 eflags = vmcb->rflags;
1261 info.bytes = vmcb->exitinfo1;
1263 port = info.fields.port; /* port used to be addr */
1264 dir = info.fields.type; /* direction */
1265 if (info.fields.sz32)
1266 size = 4;
1267 else if (info.fields.sz16)
1268 size = 2;
1269 else
1270 size = 1;
1272 cr0 = vmcb->cr0;
1273 real = (eflags & X86_EFLAGS_VM) || !(cr0 & X86_CR0_PE);
1275 HVM_DBG_LOG(DBG_LEVEL_IO,
1276 "svm_io_instruction: port 0x%lx real %d, eip=%lx:%lx, "
1277 "exit_qualification = %lx",
1278 (unsigned long) port, real, cs, eip, (unsigned long)info.bytes);
1280 /*
1281 * On SVM, the RIP of the intruction following the IN/OUT is saved in
1282 * ExitInfo2
1283 */
1284 vmcb->rip = vmcb->exitinfo2;
1286 /* string instruction */
1287 if (info.fields.str)
1289 unsigned long addr, count = 1;
1290 int sign = regs->eflags & EF_DF ? -1 : 1;
1292 addr = svm_get_io_address(vmcb, regs, dir, real);
1294 /* "rep" prefix */
1295 if (info.fields.rep)
1297 mmio_opp->flags |= REPZ;
1298 count = real ? regs->ecx & 0xFFFF : regs->ecx;
1301 /*
1302 * Handle string pio instructions that cross pages or that
1303 * are unaligned. See the comments in hvm_platform.c/handle_mmio()
1304 */
1305 if ((addr & PAGE_MASK) != ((addr + size - 1) & PAGE_MASK))
1307 unsigned long value = 0;
1309 mmio_opp->flags |= OVERLAP;
1311 if (dir == IOREQ_WRITE)
1312 hvm_copy(&value, addr, size, HVM_COPY_IN);
1314 send_pio_req(regs, port, 1, size, value, dir, 0);
1316 else
1318 if ((addr & PAGE_MASK) != ((addr + count * size - 1) & PAGE_MASK))
1320 if (sign > 0)
1321 count = (PAGE_SIZE - (addr & ~PAGE_MASK)) / size;
1322 else
1323 count = (addr & ~PAGE_MASK) / size;
1326 send_pio_req(regs, port, count, size, addr, dir, 1);
1329 else
1331 if (port == 0xe9 && dir == IOREQ_WRITE && size == 1)
1332 hvm_print_line(v, regs->eax); /* guest debug output */
1334 send_pio_req(regs, port, 1, size, regs->eax, dir, 0);
1339 static int svm_set_cr0(unsigned long value)
1341 struct vcpu *v = current;
1342 unsigned long mfn;
1343 int paging_enabled;
1344 struct vmcb_struct *vmcb = v->arch.hvm_svm.vmcb;
1346 ASSERT(vmcb);
1348 /* We don't want to lose PG. ET is reserved and should be always be 1*/
1349 paging_enabled = svm_paging_enabled(v);
1350 value |= X86_CR0_ET;
1351 vmcb->cr0 = value | X86_CR0_PG;
1352 v->arch.hvm_svm.cpu_shadow_cr0 = value;
1354 /* TS cleared? Then initialise FPU now. */
1355 if ( !(value & X86_CR0_TS) )
1357 setup_fpu(v);
1358 vmcb->exception_intercepts &= ~EXCEPTION_BITMAP_NM;
1361 HVM_DBG_LOG(DBG_LEVEL_VMMU, "Update CR0 value = %lx\n", value);
1363 if ((value & X86_CR0_PE) && (value & X86_CR0_PG) && !paging_enabled)
1365 /* The guest CR3 must be pointing to the guest physical. */
1366 if (!VALID_MFN(mfn =
1367 get_mfn_from_gpfn(v->arch.hvm_svm.cpu_cr3 >> PAGE_SHIFT))
1368 || !get_page(mfn_to_page(mfn), v->domain))
1370 printk("Invalid CR3 value = %lx\n", v->arch.hvm_svm.cpu_cr3);
1371 domain_crash_synchronous(); /* need to take a clean path */
1374 #if defined(__x86_64__)
1375 if (test_bit(SVM_CPU_STATE_LME_ENABLED, &v->arch.hvm_svm.cpu_state)
1376 && !test_bit(SVM_CPU_STATE_PAE_ENABLED,
1377 &v->arch.hvm_svm.cpu_state))
1379 HVM_DBG_LOG(DBG_LEVEL_1, "Enable paging before PAE enable\n");
1380 svm_inject_exception(vmcb, TRAP_gp_fault, 0);
1383 if (test_bit(SVM_CPU_STATE_LME_ENABLED, &v->arch.hvm_svm.cpu_state))
1385 /* Here the PAE is should to be opened */
1386 HVM_DBG_LOG(DBG_LEVEL_1, "Enable the Long mode\n");
1387 set_bit(SVM_CPU_STATE_LMA_ENABLED,
1388 &v->arch.hvm_svm.cpu_state);
1389 #if 0
1390 __vmread(VM_ENTRY_CONTROLS, &vm_entry_value);
1391 vm_entry_value |= VM_ENTRY_CONTROLS_IA32E_MODE;
1392 __vmwrite(VM_ENTRY_CONTROLS, vm_entry_value);
1393 #else
1394 printk("Cannot yet set SVM_CPU_STATE_LMA_ENABLED\n");
1395 domain_crash_synchronous();
1396 #endif
1398 #if CONFIG_PAGING_LEVELS >= 4
1399 if (!shadow_set_guest_paging_levels(v->domain, 4))
1401 printk("Unsupported guest paging levels\n");
1402 domain_crash_synchronous(); /* need to take a clean path */
1404 #endif
1406 else
1408 #if CONFIG_PAGING_LEVELS >= 4
1409 if (!shadow_set_guest_paging_levels(v->domain, 2))
1411 printk("Unsupported guest paging levels\n");
1412 domain_crash_synchronous(); /* need to take a clean path */
1414 #endif
1417 #if 0
1418 unsigned long crn;
1420 /* update CR4's PAE if needed */
1421 __vmread(GUEST_CR4, &crn);
1422 if ((!(crn & X86_CR4_PAE))
1423 && test_bit(SVM_CPU_STATE_PAE_ENABLED,
1424 &v->arch.hvm_svm.cpu_state))
1426 HVM_DBG_LOG(DBG_LEVEL_1, "enable PAE on cr4\n");
1427 __vmwrite(GUEST_CR4, crn | X86_CR4_PAE);
1429 #else
1430 printk("Cannot yet set SVM_CPU_STATE_PAE_ENABLED\n");
1431 domain_crash_synchronous();
1432 #endif
1433 #elif defined(__i386__)
1435 unsigned long old_base_mfn;
1436 old_base_mfn = pagetable_get_pfn(v->arch.guest_table);
1437 if (old_base_mfn)
1438 put_page(mfn_to_page(old_base_mfn));
1440 #endif
1442 /* Now arch.guest_table points to machine physical. */
1443 v->arch.guest_table = mk_pagetable(mfn << PAGE_SHIFT);
1444 update_pagetables(v);
1446 HVM_DBG_LOG(DBG_LEVEL_VMMU, "New arch.guest_table = %lx",
1447 (unsigned long) (mfn << PAGE_SHIFT));
1449 set_bit(ARCH_SVM_VMCB_ASSIGN_ASID, &v->arch.hvm_svm.flags);
1450 vmcb->cr3 = pagetable_get_paddr(v->arch.shadow_table);
1452 /* arch->shadow_table should hold the next CR3 for shadow */
1453 HVM_DBG_LOG(DBG_LEVEL_VMMU, "Update CR3 value = %lx, mfn = %lx\n",
1454 v->arch.hvm_svm.cpu_cr3, mfn);
1457 /*
1458 * SVM implements paged real-mode and when we return to real-mode
1459 * we revert back to the physical mappings that the domain builder
1460 * created.
1461 */
1462 if ((value & X86_CR0_PE) == 0) {
1463 if (value & X86_CR0_PG) {
1464 svm_inject_exception(vmcb, TRAP_gp_fault, 0);
1465 return 0;
1468 set_bit(ARCH_SVM_VMCB_ASSIGN_ASID, &v->arch.hvm_svm.flags);
1469 vmcb->cr3 = pagetable_get_paddr(v->domain->arch.phys_table);
1472 return 1;
1476 /*
1477 * Read from control registers. CR0 and CR4 are read from the shadow.
1478 */
1479 static void mov_from_cr(int cr, int gp, struct cpu_user_regs *regs)
1481 unsigned long value = 0;
1482 struct vcpu *v = current;
1483 struct vmcb_struct *vmcb;
1485 vmcb = v->arch.hvm_svm.vmcb;
1486 ASSERT(vmcb);
1488 switch (cr)
1490 case 0:
1491 value = v->arch.hvm_svm.cpu_shadow_cr0;
1492 break;
1493 case 2:
1494 value = vmcb->cr2;
1495 break;
1496 case 3:
1497 value = (unsigned long) v->arch.hvm_svm.cpu_cr3;
1498 break;
1499 case 4:
1500 value = vmcb->cr4;
1501 break;
1502 case 8:
1503 #if 0
1504 value = vmcb->m_cr8;
1505 #else
1506 ASSERT(0);
1507 #endif
1508 break;
1510 default:
1511 __hvm_bug(regs);
1514 set_reg(gp, value, regs, vmcb);
1516 HVM_DBG_LOG(DBG_LEVEL_VMMU, "mov_from_cr: CR%d, value = %lx,", cr, value);
1520 /*
1521 * Write to control registers
1522 */
1523 static int mov_to_cr(int gpreg, int cr, struct cpu_user_regs *regs)
1525 unsigned long value;
1526 unsigned long old_cr;
1527 struct vcpu *v = current;
1528 struct vmcb_struct *vmcb = v->arch.hvm_svm.vmcb;
1530 ASSERT(vmcb);
1532 value = get_reg(gpreg, regs, vmcb);
1534 HVM_DBG_LOG(DBG_LEVEL_1, "mov_to_cr: CR%d, value = %lx,", cr, value);
1535 HVM_DBG_LOG(DBG_LEVEL_1, "current = %lx,", (unsigned long) current);
1537 switch (cr)
1539 case 0:
1540 return svm_set_cr0(value);
1542 case 3:
1544 unsigned long old_base_mfn, mfn;
1546 /* If paging is not enabled yet, simply copy the value to CR3. */
1547 if (!svm_paging_enabled(v)) {
1548 v->arch.hvm_svm.cpu_cr3 = value;
1549 break;
1551 set_bit(ARCH_SVM_VMCB_ASSIGN_ASID, &v->arch.hvm_svm.flags);
1553 /* We make a new one if the shadow does not exist. */
1554 if (value == v->arch.hvm_svm.cpu_cr3)
1556 /*
1557 * This is simple TLB flush, implying the guest has
1558 * removed some translation or changed page attributes.
1559 * We simply invalidate the shadow.
1560 */
1561 mfn = get_mfn_from_gpfn(value >> PAGE_SHIFT);
1562 if (mfn != pagetable_get_pfn(v->arch.guest_table))
1563 __hvm_bug(regs);
1564 shadow_sync_all(v->domain);
1566 else
1568 /*
1569 * If different, make a shadow. Check if the PDBR is valid
1570 * first.
1571 */
1572 HVM_DBG_LOG(DBG_LEVEL_VMMU, "CR3 value = %lx", value);
1573 if (((value >> PAGE_SHIFT) > v->domain->max_pages)
1574 || !VALID_MFN(mfn = get_mfn_from_gpfn(value >> PAGE_SHIFT))
1575 || !get_page(mfn_to_page(mfn), v->domain))
1577 printk("Invalid CR3 value=%lx\n", value);
1578 domain_crash_synchronous(); /* need to take a clean path */
1581 old_base_mfn = pagetable_get_pfn(v->arch.guest_table);
1582 v->arch.guest_table = mk_pagetable(mfn << PAGE_SHIFT);
1584 if (old_base_mfn)
1585 put_page(mfn_to_page(old_base_mfn));
1587 update_pagetables(v);
1589 /* arch.shadow_table should now hold the next CR3 for shadow*/
1590 v->arch.hvm_svm.cpu_cr3 = value;
1591 HVM_DBG_LOG(DBG_LEVEL_VMMU, "Update CR3 value = %lx", value);
1592 vmcb->cr3 = pagetable_get_paddr(v->arch.shadow_table);
1594 break;
1597 case 4:
1598 /* CR4 */
1599 if (value & X86_CR4_PAE)
1600 __hvm_bug(regs); /* not implemented */
1602 old_cr = vmcb->cr4;
1604 vmcb->cr4 = value;
1606 /*
1607 * Writing to CR4 to modify the PSE, PGE, or PAE flag invalidates
1608 * all TLB entries except global entries.
1609 */
1610 if ((old_cr ^ value) & (X86_CR4_PSE | X86_CR4_PGE | X86_CR4_PAE))
1612 set_bit(ARCH_SVM_VMCB_ASSIGN_ASID, &v->arch.hvm_svm.flags);
1613 shadow_sync_all(v->domain);
1615 break;
1617 default:
1618 printk("invalid cr: %d\n", cr);
1619 __hvm_bug(regs);
1622 return 1;
1626 #define ARR_SIZE(x) (sizeof(x) / sizeof(x[0]))
1629 static int svm_cr_access(struct vcpu *v, unsigned int cr, unsigned int type,
1630 struct cpu_user_regs *regs)
1632 struct vmcb_struct *vmcb = v->arch.hvm_svm.vmcb;
1633 unsigned int inst_len = 0;
1634 unsigned int gpreg;
1635 unsigned long value;
1636 u8 buffer[6];
1637 int result = 1;
1638 enum instruction_index list_a[] = {INSTR_MOV2CR, INSTR_CLTS, INSTR_LMSW};
1639 enum instruction_index list_b[] = {INSTR_MOVCR2, INSTR_SMSW};
1640 enum instruction_index match;
1642 ASSERT(vmcb);
1644 inst_copy_from_guest(buffer, svm_rip2pointer(vmcb), sizeof(buffer));
1646 if (type == TYPE_MOV_TO_CR)
1648 inst_len = __get_instruction_length_from_list(vmcb, list_a,
1649 ARR_SIZE(list_a), buffer, &match);
1651 else
1653 inst_len = __get_instruction_length_from_list(vmcb, list_b,
1654 ARR_SIZE(list_b), buffer, &match);
1657 HVM_DBG_LOG(DBG_LEVEL_1, "eip = %lx", (unsigned long) vmcb->rip);
1659 switch (match)
1661 case INSTR_MOV2CR:
1662 gpreg = decode_src_reg(buffer[2]);
1663 result = mov_to_cr(gpreg, cr, regs);
1664 break;
1666 case INSTR_MOVCR2:
1667 gpreg = decode_src_reg(buffer[2]);
1668 mov_from_cr(cr, gpreg, regs);
1669 break;
1671 case INSTR_CLTS:
1672 /* TS being cleared means that it's time to restore fpu state. */
1673 setup_fpu(current);
1674 vmcb->exception_intercepts &= ~EXCEPTION_BITMAP_NM;
1675 vmcb->cr0 &= ~X86_CR0_TS; /* clear TS */
1676 v->arch.hvm_svm.cpu_shadow_cr0 &= ~X86_CR0_TS; /* clear TS */
1677 break;
1679 case INSTR_LMSW:
1680 if (svm_dbg_on)
1681 svm_dump_inst(svm_rip2pointer(vmcb));
1683 gpreg = decode_src_reg(buffer[2]);
1684 value = get_reg(gpreg, regs, vmcb) & 0xF;
1686 if (svm_dbg_on)
1687 printk("CR0-LMSW value=%lx, reg=%d, inst_len=%d\n", value, gpreg,
1688 inst_len);
1690 value = (v->arch.hvm_svm.cpu_shadow_cr0 & ~0xF) | value;
1692 if (svm_dbg_on)
1693 printk("CR0-LMSW CR0 - New value=%lx\n", value);
1695 result = svm_set_cr0(value);
1696 break;
1698 case INSTR_SMSW:
1699 svm_dump_inst(svm_rip2pointer(vmcb));
1700 value = v->arch.hvm_svm.cpu_shadow_cr0;
1701 gpreg = decode_src_reg(buffer[2]);
1702 set_reg(gpreg, value, regs, vmcb);
1704 if (svm_dbg_on)
1705 printk("CR0-SMSW value=%lx, reg=%d, inst_len=%d\n", value, gpreg,
1706 inst_len);
1707 break;
1709 default:
1710 __hvm_bug(regs);
1711 break;
1714 ASSERT(inst_len);
1716 __update_guest_eip(vmcb, inst_len);
1718 return result;
1721 static inline void svm_do_msr_access(struct vcpu *v, struct cpu_user_regs *regs)
1723 struct vmcb_struct *vmcb = v->arch.hvm_svm.vmcb;
1724 unsigned int inst_len;
1725 int64_t tsc_sum;
1727 ASSERT(vmcb);
1729 HVM_DBG_LOG(DBG_LEVEL_1, "svm_do_msr_access: ecx=%lx, eax=%lx, edx=%lx, "
1730 "exitinfo = %lx", (unsigned long)regs->ecx,
1731 (unsigned long)regs->eax, (unsigned long)regs->edx,
1732 (unsigned long)vmcb->exitinfo1);
1734 /* is it a read? */
1735 if (vmcb->exitinfo1 == 0)
1737 inst_len = __get_instruction_length(vmcb, INSTR_RDMSR, NULL);
1739 regs->edx = 0;
1740 switch (regs->ecx)
1742 case MSR_IA32_SYSENTER_CS:
1743 regs->eax = vmcb->sysenter_cs;
1744 break;
1745 case MSR_IA32_SYSENTER_ESP:
1746 regs->eax = vmcb->sysenter_esp;
1747 break;
1748 case MSR_IA32_SYSENTER_EIP:
1749 regs->eax = vmcb->sysenter_eip;
1750 break;
1751 case MSR_IA32_TIME_STAMP_COUNTER:
1752 __asm__ __volatile__("rdtsc" : "=a" (regs->eax), "=d" (regs->edx));
1753 tsc_sum = regs->edx;
1754 tsc_sum = (tsc_sum << 32) + regs->eax;
1755 tsc_sum += (int64_t) vmcb->tsc_offset;
1756 regs->eax = tsc_sum & 0xFFFFFFFF;
1757 regs->edx = (tsc_sum >> 32) & 0xFFFFFFFF;
1758 break;
1759 default:
1760 if (long_mode_do_msr_read(regs))
1761 goto done;
1762 rdmsr_safe(regs->ecx, regs->eax, regs->edx);
1763 break;
1766 else
1768 inst_len = __get_instruction_length(vmcb, INSTR_WRMSR, NULL);
1770 switch (regs->ecx)
1772 case MSR_IA32_SYSENTER_CS:
1773 vmcb->sysenter_cs = regs->eax;
1774 break;
1775 case MSR_IA32_SYSENTER_ESP:
1776 vmcb->sysenter_esp = regs->eax;
1777 break;
1778 case MSR_IA32_SYSENTER_EIP:
1779 vmcb->sysenter_eip = regs->eax;
1780 break;
1781 default:
1782 long_mode_do_msr_write(regs);
1783 break;
1787 done:
1789 HVM_DBG_LOG(DBG_LEVEL_1, "svm_do_msr_access returns: "
1790 "ecx=%lx, eax=%lx, edx=%lx",
1791 (unsigned long)regs->ecx, (unsigned long)regs->eax,
1792 (unsigned long)regs->edx);
1794 __update_guest_eip(vmcb, inst_len);
1798 /*
1799 * Need to use this exit to reschedule
1800 */
1801 static inline void svm_vmexit_do_hlt(struct vmcb_struct *vmcb)
1803 struct vcpu *v = current;
1804 struct hvm_virpit *vpit = &v->domain->arch.hvm_domain.vpit;
1805 s_time_t next_pit = -1, next_wakeup;
1807 __update_guest_eip(vmcb, 1);
1809 if ( !v->vcpu_id )
1810 next_pit = get_pit_scheduled(v, vpit);
1811 next_wakeup = get_apictime_scheduled(v);
1812 if ( (next_pit != -1 && next_pit < next_wakeup) || next_wakeup == -1 )
1813 next_wakeup = next_pit;
1814 if ( next_wakeup != - 1 )
1815 set_timer(&current->arch.hvm_svm.hlt_timer, next_wakeup);
1816 /* temporary workaround for 8828/8822 evtchn patches causing SVM failure.
1817 hvm_safe_block();
1818 */
1822 static inline void svm_vmexit_do_mwait(void)
1827 #ifdef XEN_DEBUGGER
1828 static void svm_debug_save_cpu_user_regs(struct vmcb_struct *vmcb,
1829 struct cpu_user_regs *regs)
1831 regs->eip = vmcb->rip;
1832 regs->esp = vmcb->rsp;
1833 regs->eflags = vmcb->rflags;
1835 regs->xcs = vmcb->cs.sel;
1836 regs->xds = vmcb->ds.sel;
1837 regs->xes = vmcb->es.sel;
1838 regs->xfs = vmcb->fs.sel;
1839 regs->xgs = vmcb->gs.sel;
1840 regs->xss = vmcb->ss.sel;
1844 static void svm_debug_restore_cpu_user_regs(struct cpu_user_regs *regs)
1846 vmcb->ss.sel = regs->xss;
1847 vmcb->rsp = regs->esp;
1848 vmcb->rflags = regs->eflags;
1849 vmcb->cs.sel = regs->xcs;
1850 vmcb->rip = regs->eip;
1852 vmcb->gs.sel = regs->xgs;
1853 vmcb->fs.sel = regs->xfs;
1854 vmcb->es.sel = regs->xes;
1855 vmcb->ds.sel = regs->xds;
1857 #endif
1860 void svm_handle_invlpg(const short invlpga, struct cpu_user_regs *regs)
1862 struct vcpu *v = current;
1863 u8 opcode[MAX_INST_SIZE], prefix, length = MAX_INST_SIZE;
1864 unsigned long g_vaddr;
1865 unsigned int inst_len;
1866 struct vmcb_struct *vmcb = v->arch.hvm_svm.vmcb;
1868 ASSERT(vmcb);
1869 /*
1870 * Unknown how many bytes the invlpg instruction will take. Use the
1871 * maximum instruction length here
1872 */
1873 if (inst_copy_from_guest(opcode, svm_rip2pointer(vmcb), length) < length)
1875 printk("svm_handle_invlpg (): Error reading memory %d bytes\n", length);
1876 __hvm_bug(regs);
1879 if (invlpga)
1881 inst_len = __get_instruction_length(vmcb, INSTR_INVLPGA, opcode);
1882 __update_guest_eip(vmcb, inst_len);
1884 /*
1885 * The address is implicit on this instruction At the moment, we don't
1886 * use ecx (ASID) to identify individual guests pages
1887 */
1888 g_vaddr = regs->eax;
1890 else
1892 /* What about multiple prefix codes? */
1893 prefix = (is_prefix(opcode[0])?opcode[0]:0);
1894 inst_len = __get_instruction_length(vmcb, INSTR_INVLPG, opcode);
1896 inst_len--;
1897 length -= inst_len;
1899 /*
1900 * Decode memory operand of the instruction including ModRM, SIB, and
1901 * displacement to get effecticve address and length in bytes. Assume
1902 * the system in either 32- or 64-bit mode.
1903 */
1904 g_vaddr = get_effective_addr_modrm64(vmcb, regs, prefix,
1905 &opcode[inst_len], &length);
1907 inst_len += length;
1908 __update_guest_eip (vmcb, inst_len);
1911 /* Overkill, we may not this */
1912 set_bit(ARCH_SVM_VMCB_ASSIGN_ASID, &v->arch.hvm_svm.flags);
1913 shadow_invlpg(v, g_vaddr);
1917 /*
1918 * Reset to realmode causes execution to start at 0xF000:0xFFF0 in
1919 * 16-bit realmode. Basically, this mimics a processor reset.
1921 * returns 0 on success, non-zero otherwise
1922 */
1923 static int svm_do_vmmcall_reset_to_realmode(struct vcpu *v,
1924 struct cpu_user_regs *regs)
1926 struct vmcb_struct *vmcb;
1928 ASSERT(v);
1929 ASSERT(regs);
1931 vmcb = v->arch.hvm_svm.vmcb;
1933 ASSERT(vmcb);
1935 /* clear the vmcb and user regs */
1936 memset(regs, 0, sizeof(struct cpu_user_regs));
1938 /* VMCB Control */
1939 vmcb->tsc_offset = 0;
1941 /* VMCB State */
1942 vmcb->cr0 = X86_CR0_ET | X86_CR0_PG;
1943 v->arch.hvm_svm.cpu_shadow_cr0 = X86_CR0_ET;
1945 vmcb->cr2 = 0;
1946 vmcb->cr4 = 0;
1948 /* This will jump to ROMBIOS */
1949 vmcb->rip = 0xFFF0;
1951 /* setup the segment registers and all their hidden states */
1952 vmcb->cs.sel = 0xF000;
1953 vmcb->cs.attributes.bytes = 0x089b;
1954 vmcb->cs.limit = 0xffff;
1955 vmcb->cs.base = 0x000F0000;
1957 vmcb->ss.sel = 0x00;
1958 vmcb->ss.attributes.bytes = 0x0893;
1959 vmcb->ss.limit = 0xffff;
1960 vmcb->ss.base = 0x00;
1962 vmcb->ds.sel = 0x00;
1963 vmcb->ds.attributes.bytes = 0x0893;
1964 vmcb->ds.limit = 0xffff;
1965 vmcb->ds.base = 0x00;
1967 vmcb->es.sel = 0x00;
1968 vmcb->es.attributes.bytes = 0x0893;
1969 vmcb->es.limit = 0xffff;
1970 vmcb->es.base = 0x00;
1972 vmcb->fs.sel = 0x00;
1973 vmcb->fs.attributes.bytes = 0x0893;
1974 vmcb->fs.limit = 0xffff;
1975 vmcb->fs.base = 0x00;
1977 vmcb->gs.sel = 0x00;
1978 vmcb->gs.attributes.bytes = 0x0893;
1979 vmcb->gs.limit = 0xffff;
1980 vmcb->gs.base = 0x00;
1982 vmcb->ldtr.sel = 0x00;
1983 vmcb->ldtr.attributes.bytes = 0x0000;
1984 vmcb->ldtr.limit = 0x0;
1985 vmcb->ldtr.base = 0x00;
1987 vmcb->gdtr.sel = 0x00;
1988 vmcb->gdtr.attributes.bytes = 0x0000;
1989 vmcb->gdtr.limit = 0x0;
1990 vmcb->gdtr.base = 0x00;
1992 vmcb->tr.sel = 0;
1993 vmcb->tr.attributes.bytes = 0;
1994 vmcb->tr.limit = 0x0;
1995 vmcb->tr.base = 0;
1997 vmcb->idtr.sel = 0x00;
1998 vmcb->idtr.attributes.bytes = 0x0000;
1999 vmcb->idtr.limit = 0x3ff;
2000 vmcb->idtr.base = 0x00;
2002 vmcb->rax = 0;
2004 return 0;
2008 /*
2009 * svm_do_vmmcall - SVM VMMCALL handler
2011 * returns 0 on success, non-zero otherwise
2012 */
2013 static int svm_do_vmmcall(struct vcpu *v, struct cpu_user_regs *regs)
2015 struct vmcb_struct *vmcb = v->arch.hvm_svm.vmcb;
2016 unsigned int inst_len;
2018 ASSERT(vmcb);
2019 ASSERT(regs);
2021 inst_len = __get_instruction_length(vmcb, INSTR_VMCALL, NULL);
2023 /* VMMCALL sanity check */
2024 if (vmcb->cpl > get_vmmcall_cpl(regs->edi))
2026 printf("VMMCALL CPL check failed\n");
2027 return -1;
2030 /* handle the request */
2031 switch (regs->edi)
2033 case VMMCALL_RESET_TO_REALMODE:
2034 if (svm_do_vmmcall_reset_to_realmode(v, regs))
2036 printf("svm_do_vmmcall_reset_to_realmode() failed\n");
2037 return -1;
2040 /* since we just reset the VMCB, return without adjusting the eip */
2041 return 0;
2042 case VMMCALL_DEBUG:
2043 printf("DEBUG features not implemented yet\n");
2044 break;
2045 default:
2046 break;
2049 hvm_print_line(v, regs->eax); /* provides the current domain */
2051 __update_guest_eip(vmcb, inst_len);
2052 return 0;
2056 void svm_dump_inst(unsigned long eip)
2058 u8 opcode[256];
2059 unsigned long ptr;
2060 int len;
2061 int i;
2063 ptr = eip & ~0xff;
2064 len = 0;
2066 if (hvm_copy(opcode, ptr, sizeof(opcode), HVM_COPY_IN))
2067 len = sizeof(opcode);
2069 printf("Code bytes around(len=%d) %lx:", len, eip);
2070 for (i = 0; i < len; i++)
2072 if ((i & 0x0f) == 0)
2073 printf("\n%08lx:", ptr+i);
2075 printf("%02x ", opcode[i]);
2078 printf("\n");
2082 void svm_dump_regs(const char *from, struct cpu_user_regs *regs)
2084 struct vcpu *v = current;
2085 struct vmcb_struct *vmcb = v->arch.hvm_svm.vmcb;
2086 unsigned long pt = pagetable_get_paddr(v->arch.shadow_table);
2088 printf("%s: guest registers from %s:\n", __func__, from);
2089 #if defined (__x86_64__)
2090 printk("rax: %016lx rbx: %016lx rcx: %016lx\n",
2091 regs->rax, regs->rbx, regs->rcx);
2092 printk("rdx: %016lx rsi: %016lx rdi: %016lx\n",
2093 regs->rdx, regs->rsi, regs->rdi);
2094 printk("rbp: %016lx rsp: %016lx r8: %016lx\n",
2095 regs->rbp, regs->rsp, regs->r8);
2096 printk("r9: %016lx r10: %016lx r11: %016lx\n",
2097 regs->r9, regs->r10, regs->r11);
2098 printk("r12: %016lx r13: %016lx r14: %016lx\n",
2099 regs->r12, regs->r13, regs->r14);
2100 printk("r15: %016lx cr0: %016lx cr3: %016lx\n",
2101 regs->r15, v->arch.hvm_svm.cpu_shadow_cr0, vmcb->cr3);
2102 #else
2103 printf("eax: %08x, ebx: %08x, ecx: %08x, edx: %08x\n",
2104 regs->eax, regs->ebx, regs->ecx, regs->edx);
2105 printf("edi: %08x, esi: %08x, ebp: %08x, esp: %08x\n",
2106 regs->edi, regs->esi, regs->ebp, regs->esp);
2107 printf("%s: guest cr0: %lx\n", __func__,
2108 v->arch.hvm_svm.cpu_shadow_cr0);
2109 printf("guest CR3 = %llx\n", vmcb->cr3);
2110 #endif
2111 printf("%s: pt = %lx\n", __func__, pt);
2115 void svm_dump_host_regs(const char *from)
2117 struct vcpu *v = current;
2118 unsigned long pt = pt = pagetable_get_paddr(v->arch.monitor_table);
2119 unsigned long cr3, cr0;
2120 printf("Host registers at %s\n", from);
2122 __asm__ __volatile__ ("\tmov %%cr0,%0\n"
2123 "\tmov %%cr3,%1\n"
2124 : "=r" (cr0), "=r"(cr3));
2125 printf("%s: pt = %lx, cr3 = %lx, cr0 = %lx\n", __func__, pt, cr3, cr0);
2128 #ifdef SVM_EXTRA_DEBUG
2129 static char *exit_reasons[] = {
2130 [VMEXIT_CR0_READ] = "CR0_READ",
2131 [VMEXIT_CR1_READ] = "CR1_READ",
2132 [VMEXIT_CR2_READ] = "CR2_READ",
2133 [VMEXIT_CR3_READ] = "CR3_READ",
2134 [VMEXIT_CR4_READ] = "CR4_READ",
2135 [VMEXIT_CR5_READ] = "CR5_READ",
2136 [VMEXIT_CR6_READ] = "CR6_READ",
2137 [VMEXIT_CR7_READ] = "CR7_READ",
2138 [VMEXIT_CR8_READ] = "CR8_READ",
2139 [VMEXIT_CR9_READ] = "CR9_READ",
2140 [VMEXIT_CR10_READ] = "CR10_READ",
2141 [VMEXIT_CR11_READ] = "CR11_READ",
2142 [VMEXIT_CR12_READ] = "CR12_READ",
2143 [VMEXIT_CR13_READ] = "CR13_READ",
2144 [VMEXIT_CR14_READ] = "CR14_READ",
2145 [VMEXIT_CR15_READ] = "CR15_READ",
2146 [VMEXIT_CR0_WRITE] = "CR0_WRITE",
2147 [VMEXIT_CR1_WRITE] = "CR1_WRITE",
2148 [VMEXIT_CR2_WRITE] = "CR2_WRITE",
2149 [VMEXIT_CR3_WRITE] = "CR3_WRITE",
2150 [VMEXIT_CR4_WRITE] = "CR4_WRITE",
2151 [VMEXIT_CR5_WRITE] = "CR5_WRITE",
2152 [VMEXIT_CR6_WRITE] = "CR6_WRITE",
2153 [VMEXIT_CR7_WRITE] = "CR7_WRITE",
2154 [VMEXIT_CR8_WRITE] = "CR8_WRITE",
2155 [VMEXIT_CR9_WRITE] = "CR9_WRITE",
2156 [VMEXIT_CR10_WRITE] = "CR10_WRITE",
2157 [VMEXIT_CR11_WRITE] = "CR11_WRITE",
2158 [VMEXIT_CR12_WRITE] = "CR12_WRITE",
2159 [VMEXIT_CR13_WRITE] = "CR13_WRITE",
2160 [VMEXIT_CR14_WRITE] = "CR14_WRITE",
2161 [VMEXIT_CR15_WRITE] = "CR15_WRITE",
2162 [VMEXIT_DR0_READ] = "DR0_READ",
2163 [VMEXIT_DR1_READ] = "DR1_READ",
2164 [VMEXIT_DR2_READ] = "DR2_READ",
2165 [VMEXIT_DR3_READ] = "DR3_READ",
2166 [VMEXIT_DR4_READ] = "DR4_READ",
2167 [VMEXIT_DR5_READ] = "DR5_READ",
2168 [VMEXIT_DR6_READ] = "DR6_READ",
2169 [VMEXIT_DR7_READ] = "DR7_READ",
2170 [VMEXIT_DR8_READ] = "DR8_READ",
2171 [VMEXIT_DR9_READ] = "DR9_READ",
2172 [VMEXIT_DR10_READ] = "DR10_READ",
2173 [VMEXIT_DR11_READ] = "DR11_READ",
2174 [VMEXIT_DR12_READ] = "DR12_READ",
2175 [VMEXIT_DR13_READ] = "DR13_READ",
2176 [VMEXIT_DR14_READ] = "DR14_READ",
2177 [VMEXIT_DR15_READ] = "DR15_READ",
2178 [VMEXIT_DR0_WRITE] = "DR0_WRITE",
2179 [VMEXIT_DR1_WRITE] = "DR1_WRITE",
2180 [VMEXIT_DR2_WRITE] = "DR2_WRITE",
2181 [VMEXIT_DR3_WRITE] = "DR3_WRITE",
2182 [VMEXIT_DR4_WRITE] = "DR4_WRITE",
2183 [VMEXIT_DR5_WRITE] = "DR5_WRITE",
2184 [VMEXIT_DR6_WRITE] = "DR6_WRITE",
2185 [VMEXIT_DR7_WRITE] = "DR7_WRITE",
2186 [VMEXIT_DR8_WRITE] = "DR8_WRITE",
2187 [VMEXIT_DR9_WRITE] = "DR9_WRITE",
2188 [VMEXIT_DR10_WRITE] = "DR10_WRITE",
2189 [VMEXIT_DR11_WRITE] = "DR11_WRITE",
2190 [VMEXIT_DR12_WRITE] = "DR12_WRITE",
2191 [VMEXIT_DR13_WRITE] = "DR13_WRITE",
2192 [VMEXIT_DR14_WRITE] = "DR14_WRITE",
2193 [VMEXIT_DR15_WRITE] = "DR15_WRITE",
2194 [VMEXIT_EXCEPTION_DE] = "EXCEPTION_DE",
2195 [VMEXIT_EXCEPTION_DB] = "EXCEPTION_DB",
2196 [VMEXIT_EXCEPTION_NMI] = "EXCEPTION_NMI",
2197 [VMEXIT_EXCEPTION_BP] = "EXCEPTION_BP",
2198 [VMEXIT_EXCEPTION_OF] = "EXCEPTION_OF",
2199 [VMEXIT_EXCEPTION_BR] = "EXCEPTION_BR",
2200 [VMEXIT_EXCEPTION_UD] = "EXCEPTION_UD",
2201 [VMEXIT_EXCEPTION_NM] = "EXCEPTION_NM",
2202 [VMEXIT_EXCEPTION_DF] = "EXCEPTION_DF",
2203 [VMEXIT_EXCEPTION_09] = "EXCEPTION_09",
2204 [VMEXIT_EXCEPTION_TS] = "EXCEPTION_TS",
2205 [VMEXIT_EXCEPTION_NP] = "EXCEPTION_NP",
2206 [VMEXIT_EXCEPTION_SS] = "EXCEPTION_SS",
2207 [VMEXIT_EXCEPTION_GP] = "EXCEPTION_GP",
2208 [VMEXIT_EXCEPTION_PF] = "EXCEPTION_PF",
2209 [VMEXIT_EXCEPTION_15] = "EXCEPTION_15",
2210 [VMEXIT_EXCEPTION_MF] = "EXCEPTION_MF",
2211 [VMEXIT_EXCEPTION_AC] = "EXCEPTION_AC",
2212 [VMEXIT_EXCEPTION_MC] = "EXCEPTION_MC",
2213 [VMEXIT_EXCEPTION_XF] = "EXCEPTION_XF",
2214 [VMEXIT_INTR] = "INTR",
2215 [VMEXIT_NMI] = "NMI",
2216 [VMEXIT_SMI] = "SMI",
2217 [VMEXIT_INIT] = "INIT",
2218 [VMEXIT_VINTR] = "VINTR",
2219 [VMEXIT_CR0_SEL_WRITE] = "CR0_SEL_WRITE",
2220 [VMEXIT_IDTR_READ] = "IDTR_READ",
2221 [VMEXIT_GDTR_READ] = "GDTR_READ",
2222 [VMEXIT_LDTR_READ] = "LDTR_READ",
2223 [VMEXIT_TR_READ] = "TR_READ",
2224 [VMEXIT_IDTR_WRITE] = "IDTR_WRITE",
2225 [VMEXIT_GDTR_WRITE] = "GDTR_WRITE",
2226 [VMEXIT_LDTR_WRITE] = "LDTR_WRITE",
2227 [VMEXIT_TR_WRITE] = "TR_WRITE",
2228 [VMEXIT_RDTSC] = "RDTSC",
2229 [VMEXIT_RDPMC] = "RDPMC",
2230 [VMEXIT_PUSHF] = "PUSHF",
2231 [VMEXIT_POPF] = "POPF",
2232 [VMEXIT_CPUID] = "CPUID",
2233 [VMEXIT_RSM] = "RSM",
2234 [VMEXIT_IRET] = "IRET",
2235 [VMEXIT_SWINT] = "SWINT",
2236 [VMEXIT_INVD] = "INVD",
2237 [VMEXIT_PAUSE] = "PAUSE",
2238 [VMEXIT_HLT] = "HLT",
2239 [VMEXIT_INVLPG] = "INVLPG",
2240 [VMEXIT_INVLPGA] = "INVLPGA",
2241 [VMEXIT_IOIO] = "IOIO",
2242 [VMEXIT_MSR] = "MSR",
2243 [VMEXIT_TASK_SWITCH] = "TASK_SWITCH",
2244 [VMEXIT_FERR_FREEZE] = "FERR_FREEZE",
2245 [VMEXIT_SHUTDOWN] = "SHUTDOWN",
2246 [VMEXIT_VMRUN] = "VMRUN",
2247 [VMEXIT_VMMCALL] = "VMMCALL",
2248 [VMEXIT_VMLOAD] = "VMLOAD",
2249 [VMEXIT_VMSAVE] = "VMSAVE",
2250 [VMEXIT_STGI] = "STGI",
2251 [VMEXIT_CLGI] = "CLGI",
2252 [VMEXIT_SKINIT] = "SKINIT",
2253 [VMEXIT_RDTSCP] = "RDTSCP",
2254 [VMEXIT_ICEBP] = "ICEBP",
2255 [VMEXIT_NPF] = "NPF"
2256 };
2257 #endif /* SVM_EXTRA_DEBUG */
2259 #ifdef SVM_WALK_GUEST_PAGES
2260 void walk_shadow_and_guest_pt(unsigned long gva)
2262 l2_pgentry_t gpde;
2263 l2_pgentry_t spde;
2264 l1_pgentry_t gpte;
2265 l1_pgentry_t spte;
2266 struct vcpu *v = current;
2267 struct vmcb_struct *vmcb = v->arch.hvm_svm.vmcb;
2268 unsigned long gpa;
2270 gpa = gva_to_gpa( gva );
2271 printk( "gva = %lx, gpa=%lx, gCR3=%x\n", gva, gpa, (u32)vmcb->cr3 );
2272 if( !svm_paging_enabled(v) || mmio_space(gpa) )
2273 return;
2275 /* let's dump the guest and shadow page info */
2277 __guest_get_l2e(v, gva, &gpde);
2278 printk( "G-PDE = %x, flags=%x\n", gpde.l2, l2e_get_flags(gpde) );
2279 __shadow_get_l2e( v, gva, &spde );
2280 printk( "S-PDE = %x, flags=%x\n", spde.l2, l2e_get_flags(spde) );
2282 if ( unlikely(!(l2e_get_flags(gpde) & _PAGE_PRESENT)) )
2283 return;
2285 spte = l1e_empty();
2287 // This is actually overkill - we only need to make sure the hl2 is in-sync.
2288 shadow_sync_va(v, gva);
2290 gpte.l1 = 0;
2291 __copy_from_user(&gpte, &linear_pg_table[ l1_linear_offset(gva) ], sizeof(gpte) );
2292 printk( "G-PTE = %x, flags=%x\n", gpte.l1, l1e_get_flags(gpte) );
2293 __copy_from_user( &spte, &phys_to_machine_mapping[ l1e_get_pfn( gpte ) ], sizeof(spte) );
2294 printk( "S-PTE = %x, flags=%x\n", spte.l1, l1e_get_flags(spte));
2296 #endif /* SVM_WALK_GUEST_PAGES */
2298 asmlinkage void svm_vmexit_handler(struct cpu_user_regs regs)
2300 unsigned int exit_reason;
2301 unsigned long eip;
2302 struct vcpu *v = current;
2303 int error;
2304 int do_debug = 0;
2305 struct vmcb_struct *vmcb = v->arch.hvm_svm.vmcb;
2307 ASSERT(vmcb);
2309 exit_reason = vmcb->exitcode;
2310 save_svm_cpu_user_regs(v, &regs);
2311 v->arch.hvm_svm.injecting_event = 0;
2313 vmcb->tlb_control = 1;
2315 #ifdef SVM_EXTRA_DEBUG
2317 #if defined(__i386__)
2318 #define rip eip
2319 #endif
2321 static unsigned long intercepts_counter = 0;
2323 if (svm_dbg_on && exit_reason == VMEXIT_EXCEPTION_PF)
2325 if (svm_paging_enabled(v) && !mmio_space(gva_to_gpa(vmcb->exitinfo2)))
2327 printk("I%08ld,ExC=%s(%d),IP=%x:%llx,I1=%llx,I2=%llx,INT=%llx\n",
2328 intercepts_counter,
2329 exit_reasons[exit_reason], exit_reason, regs.cs,
2330 (unsigned long long) regs.rip,
2331 (unsigned long long) vmcb->exitinfo1,
2332 (unsigned long long) vmcb->exitinfo2,
2333 (unsigned long long) vmcb->exitintinfo.bytes);
2336 else if (svm_dbg_on
2337 && exit_reason != VMEXIT_IOIO
2338 && exit_reason != VMEXIT_INTR)
2341 if (exit_reasons[exit_reason])
2343 printk("I%08ld,ExC=%s(%d),IP=%x:%llx,I1=%llx,I2=%llx,INT=%llx\n",
2344 intercepts_counter,
2345 exit_reasons[exit_reason], exit_reason, regs.cs,
2346 (unsigned long long) regs.rip,
2347 (unsigned long long) vmcb->exitinfo1,
2348 (unsigned long long) vmcb->exitinfo2,
2349 (unsigned long long) vmcb->exitintinfo.bytes);
2351 else
2353 printk("I%08ld,ExC=%d(0x%x),IP=%x:%llx,I1=%llx,I2=%llx,INT=%llx\n",
2354 intercepts_counter, exit_reason, exit_reason, regs.cs,
2355 (unsigned long long) regs.rip,
2356 (unsigned long long) vmcb->exitinfo1,
2357 (unsigned long long) vmcb->exitinfo2,
2358 (unsigned long long) vmcb->exitintinfo.bytes);
2362 #ifdef SVM_WALK_GUEST_PAGES
2363 if( exit_reason == VMEXIT_EXCEPTION_PF && ( ( vmcb->exitinfo2 == vmcb->rip )|| vmcb->exitintinfo.bytes) )
2365 if (svm_paging_enabled(v) && !mmio_space(gva_to_gpa(vmcb->exitinfo2)))
2366 walk_shadow_and_guest_pt( vmcb->exitinfo2 );
2368 #endif
2370 intercepts_counter++;
2372 #if 0
2373 if (svm_dbg_on)
2374 do_debug = svm_do_debugout(exit_reason);
2375 #endif
2377 if (do_debug)
2379 printk("%s:+ guest_table = 0x%08x, monitor_table = 0x%08x, "
2380 "shadow_table = 0x%08x\n",
2381 __func__,
2382 (int) v->arch.guest_table.pfn,
2383 (int) v->arch.monitor_table.pfn,
2384 (int) v->arch.shadow_table.pfn);
2386 svm_dump_vmcb(__func__, vmcb);
2387 svm_dump_regs(__func__, &regs);
2388 svm_dump_inst(svm_rip2pointer(vmcb));
2391 #if defined(__i386__)
2392 #undef rip
2393 #endif
2396 #endif /* SVM_EXTRA_DEBUG */
2398 if (exit_reason == -1)
2400 printk("%s: exit_reason == -1 - Did someone clobber the VMCB\n",
2401 __func__);
2402 BUG();
2403 domain_crash_synchronous();
2406 perfc_incra(vmexits, exit_reason);
2407 eip = vmcb->rip;
2409 #ifdef SVM_EXTRA_DEBUG
2410 if (do_debug)
2412 printk("eip = %lx, exit_reason = %d (0x%x)\n",
2413 eip, exit_reason, exit_reason);
2415 #endif /* SVM_EXTRA_DEBUG */
2417 TRACE_3D(TRC_VMX_VMEXIT, v->domain->domain_id, eip, exit_reason);
2419 switch (exit_reason)
2421 case VMEXIT_EXCEPTION_DB:
2423 #ifdef XEN_DEBUGGER
2424 svm_debug_save_cpu_user_regs(&regs);
2425 pdb_handle_exception(1, &regs, 1);
2426 svm_debug_restore_cpu_user_regs(&regs);
2427 #else
2428 svm_store_cpu_user_regs(&regs, v);
2429 domain_pause_for_debugger();
2430 #endif
2432 break;
2434 case VMEXIT_NMI:
2435 do_nmi(&regs, 0);
2436 break;
2438 #ifdef XEN_DEBUGGER
2439 case VMEXIT_EXCEPTION_BP:
2440 svm_debug_save_cpu_user_regs(&regs);
2441 pdb_handle_exception(3, &regs, 1);
2442 svm_debug_restore_cpu_user_regs(&regs);
2443 break;
2444 #endif
2446 case VMEXIT_EXCEPTION_NM:
2447 svm_do_no_device_fault(vmcb);
2448 break;
2450 case VMEXIT_EXCEPTION_GP:
2451 /* This should probably not be trapped in the future */
2452 regs.error_code = vmcb->exitinfo1;
2453 v->arch.hvm_svm.injecting_event = 1;
2454 svm_do_general_protection_fault(v, &regs);
2455 break;
2457 case VMEXIT_EXCEPTION_PF:
2459 unsigned long va;
2460 va = vmcb->exitinfo2;
2461 regs.error_code = vmcb->exitinfo1;
2462 HVM_DBG_LOG(DBG_LEVEL_VMMU,
2463 "eax=%lx, ebx=%lx, ecx=%lx, edx=%lx, esi=%lx, edi=%lx",
2464 (unsigned long)regs.eax, (unsigned long)regs.ebx,
2465 (unsigned long)regs.ecx, (unsigned long)regs.edx,
2466 (unsigned long)regs.esi, (unsigned long)regs.edi);
2468 v->arch.hvm_vcpu.mmio_op.inst_decoder_regs = &regs;
2470 //printk("PF1\n");
2471 if (!(error = svm_do_page_fault(va, &regs)))
2473 v->arch.hvm_svm.injecting_event = 1;
2474 /* Inject #PG using Interruption-Information Fields */
2475 svm_inject_exception(vmcb, TRAP_page_fault, regs.error_code);
2477 v->arch.hvm_svm.cpu_cr2 = va;
2478 vmcb->cr2 = va;
2479 TRACE_3D(TRC_VMX_INT, v->domain->domain_id,
2480 VMEXIT_EXCEPTION_PF, va);
2482 break;
2485 case VMEXIT_EXCEPTION_DF:
2486 printk("Guest double fault");
2487 BUG();
2488 break;
2490 case VMEXIT_INTR:
2491 raise_softirq(SCHEDULE_SOFTIRQ);
2492 break;
2494 case VMEXIT_GDTR_WRITE:
2495 printk("WRITE to GDTR\n");
2496 break;
2498 case VMEXIT_TASK_SWITCH:
2499 __hvm_bug(&regs);
2500 break;
2502 case VMEXIT_CPUID:
2503 svm_vmexit_do_cpuid(vmcb, regs.eax, &regs);
2504 break;
2506 case VMEXIT_HLT:
2507 svm_vmexit_do_hlt(vmcb);
2508 break;
2510 case VMEXIT_INVLPG:
2511 svm_handle_invlpg(0, &regs);
2512 break;
2514 case VMEXIT_INVLPGA:
2515 svm_handle_invlpg(1, &regs);
2516 break;
2518 case VMEXIT_VMMCALL:
2519 svm_do_vmmcall(v, &regs);
2520 break;
2522 case VMEXIT_CR0_READ:
2523 svm_cr_access(v, 0, TYPE_MOV_FROM_CR, &regs);
2524 break;
2526 case VMEXIT_CR2_READ:
2527 svm_cr_access(v, 2, TYPE_MOV_FROM_CR, &regs);
2528 break;
2530 case VMEXIT_CR3_READ:
2531 svm_cr_access(v, 3, TYPE_MOV_FROM_CR, &regs);
2532 break;
2534 case VMEXIT_CR4_READ:
2535 svm_cr_access(v, 4, TYPE_MOV_FROM_CR, &regs);
2536 break;
2538 case VMEXIT_CR8_READ:
2539 svm_cr_access(v, 8, TYPE_MOV_FROM_CR, &regs);
2540 break;
2542 case VMEXIT_CR0_WRITE:
2543 svm_cr_access(v, 0, TYPE_MOV_TO_CR, &regs);
2544 break;
2546 case VMEXIT_CR2_WRITE:
2547 svm_cr_access(v, 2, TYPE_MOV_TO_CR, &regs);
2548 break;
2550 case VMEXIT_CR3_WRITE:
2551 svm_cr_access(v, 3, TYPE_MOV_TO_CR, &regs);
2552 local_flush_tlb();
2553 break;
2555 case VMEXIT_CR4_WRITE:
2556 svm_cr_access(v, 4, TYPE_MOV_TO_CR, &regs);
2557 break;
2559 case VMEXIT_CR8_WRITE:
2560 svm_cr_access(v, 8, TYPE_MOV_TO_CR, &regs);
2561 break;
2563 case VMEXIT_DR0_READ:
2564 svm_dr_access(v, 0, TYPE_MOV_FROM_DR, &regs);
2565 break;
2567 case VMEXIT_DR1_READ:
2568 svm_dr_access(v, 1, TYPE_MOV_FROM_DR, &regs);
2569 break;
2571 case VMEXIT_DR2_READ:
2572 svm_dr_access(v, 2, TYPE_MOV_FROM_DR, &regs);
2573 break;
2575 case VMEXIT_DR3_READ:
2576 svm_dr_access(v, 3, TYPE_MOV_FROM_DR, &regs);
2577 break;
2579 case VMEXIT_DR6_READ:
2580 svm_dr_access(v, 6, TYPE_MOV_FROM_DR, &regs);
2581 break;
2583 case VMEXIT_DR7_READ:
2584 svm_dr_access(v, 7, TYPE_MOV_FROM_DR, &regs);
2585 break;
2587 case VMEXIT_DR0_WRITE:
2588 svm_dr_access(v, 0, TYPE_MOV_TO_DR, &regs);
2589 break;
2591 case VMEXIT_DR1_WRITE:
2592 svm_dr_access(v, 1, TYPE_MOV_TO_DR, &regs);
2593 break;
2595 case VMEXIT_DR2_WRITE:
2596 svm_dr_access(v, 2, TYPE_MOV_TO_DR, &regs);
2597 break;
2599 case VMEXIT_DR3_WRITE:
2600 svm_dr_access(v, 3, TYPE_MOV_TO_DR, &regs);
2601 break;
2603 case VMEXIT_DR6_WRITE:
2604 svm_dr_access(v, 6, TYPE_MOV_TO_DR, &regs);
2605 break;
2607 case VMEXIT_DR7_WRITE:
2608 svm_dr_access(v, 7, TYPE_MOV_TO_DR, &regs);
2609 break;
2611 case VMEXIT_IOIO:
2612 svm_io_instruction(v, &regs);
2613 break;
2615 case VMEXIT_MSR:
2616 svm_do_msr_access(v, &regs);
2617 break;
2619 case VMEXIT_SHUTDOWN:
2620 printk("Guest shutdown exit\n");
2621 domain_crash_synchronous();
2622 break;
2624 default:
2625 printk("unexpected VMEXIT: exit reason = 0x%x, exitinfo1 = %llx, "
2626 "exitinfo2 = %llx\n", exit_reason,
2627 (unsigned long long)vmcb->exitinfo1,
2628 (unsigned long long)vmcb->exitinfo2);
2629 __hvm_bug(&regs); /* should not happen */
2630 break;
2633 #ifdef SVM_EXTRA_DEBUG
2634 if (do_debug)
2636 printk("%s: Done switch on vmexit_code\n", __func__);
2637 svm_dump_regs(__func__, &regs);
2640 if (do_debug)
2642 printk("vmexit_handler():- guest_table = 0x%08x, "
2643 "monitor_table = 0x%08x, shadow_table = 0x%08x\n",
2644 (int)v->arch.guest_table.pfn,
2645 (int)v->arch.monitor_table.pfn,
2646 (int)v->arch.shadow_table.pfn);
2647 printk("svm_vmexit_handler: Returning\n");
2649 #endif
2651 return;
2654 asmlinkage void svm_load_cr2(void)
2656 struct vcpu *v = current;
2658 local_irq_disable();
2659 #ifdef __i386__
2660 asm volatile("movl %0,%%cr2": :"r" (v->arch.hvm_svm.cpu_cr2));
2661 #else
2662 asm volatile("movq %0,%%cr2": :"r" (v->arch.hvm_svm.cpu_cr2));
2663 #endif
2666 asmlinkage void svm_asid(void)
2668 struct vcpu *v = current;
2669 struct vmcb_struct *vmcb = v->arch.hvm_svm.vmcb;
2670 int core = smp_processor_id();
2671 int oldcore = v->arch.hvm_svm.core;
2672 /*
2673 * if need to assign new asid or if switching cores,
2674 * then retire asid for old core, and assign new for new core.
2675 */
2676 if( v->arch.hvm_svm.core != core ) {
2677 if (svm_dbg_on)
2678 printk("old core %d new core %d\n",(int)v->arch.hvm_svm.core,(int)core);
2679 v->arch.hvm_svm.core = core;
2681 if( test_bit(ARCH_SVM_VMCB_ASSIGN_ASID, &v->arch.hvm_svm.flags) ||
2682 (oldcore != core)) {
2683 if(!asidpool_assign_next(vmcb, 1,
2684 oldcore, core)) {
2685 /* If we get here, we have a major problem */
2686 domain_crash_synchronous();
2689 clear_bit(ARCH_SVM_VMCB_ASSIGN_ASID, &v->arch.hvm_svm.flags);
2692 /*
2693 * Local variables:
2694 * mode: C
2695 * c-set-style: "BSD"
2696 * c-basic-offset: 4
2697 * tab-width: 4
2698 * indent-tabs-mode: nil
2699 * End:
2700 */