ia64/xen-unstable
changeset 10212:e0ec3587a2f0
[HVM][AMD] Support HVM SMP guests on AMD Pacifica hardware (svm platform).
Signed-off-by: K. Y. Srinivasan <ksrinivasan@novell.com>
Signed-off-by: K. Y. Srinivasan <ksrinivasan@novell.com>
author | kaf24@firebug.cl.cam.ac.uk |
---|---|
date | Tue May 30 12:32:07 2006 +0100 (2006-05-30) |
parents | 5be9e927533d |
children | 6a3462993320 |
files | xen/arch/x86/hvm/svm/svm.c |
line diff
1.1 --- a/xen/arch/x86/hvm/svm/svm.c Tue May 30 12:30:47 2006 +0100 1.2 +++ b/xen/arch/x86/hvm/svm/svm.c Tue May 30 12:32:07 2006 +0100 1.3 @@ -74,6 +74,9 @@ void svm_manual_event_injection32(struct 1.4 void svm_dump_regs(const char *from, struct cpu_user_regs *regs); 1.5 1.6 static void svm_relinquish_guest_resources(struct domain *d); 1.7 +static int svm_do_vmmcall_reset_to_realmode(struct vcpu *v, 1.8 + struct cpu_user_regs *regs); 1.9 + 1.10 1.11 1.12 extern void set_hsa_to_guest( struct arch_svm_struct *arch_svm ); 1.13 @@ -438,6 +441,42 @@ unsigned long svm_get_ctrl_reg(struct vc 1.14 return 0; /* dummy */ 1.15 } 1.16 1.17 + 1.18 +/* SVM-specific intitialization code for VCPU application processors */ 1.19 +void svm_init_ap_context(struct vcpu_guest_context *ctxt, 1.20 + int vcpuid, int trampoline_vector) 1.21 +{ 1.22 + int i; 1.23 + struct vcpu *v, *bsp = current; 1.24 + struct domain *d = bsp->domain; 1.25 + cpu_user_regs_t *regs;; 1.26 + 1.27 + 1.28 + if ((v = d->vcpu[vcpuid]) == NULL) 1.29 + { 1.30 + printk("vcpuid %d is invalid! good-bye.\n", vcpuid); 1.31 + domain_crash_synchronous(); 1.32 + } 1.33 + regs = &v->arch.guest_context.user_regs; 1.34 + 1.35 + memset(ctxt, 0, sizeof(*ctxt)); 1.36 + for (i = 0; i < 256; ++i) 1.37 + { 1.38 + ctxt->trap_ctxt[i].vector = i; 1.39 + ctxt->trap_ctxt[i].cs = FLAT_KERNEL_CS; 1.40 + } 1.41 + 1.42 + 1.43 + /* 1.44 + * We execute the trampoline code in real mode. The trampoline vector 1.45 + * passed to us is page alligned and is the physicall frame number for 1.46 + * the code. We will execute this code in real mode. 1.47 + */ 1.48 + ctxt->user_regs.eip = 0x0; 1.49 + ctxt->user_regs.cs = (trampoline_vector << 8); 1.50 + ctxt->flags = VGCF_HVM_GUEST; 1.51 +} 1.52 + 1.53 int start_svm(void) 1.54 { 1.55 u32 eax, ecx, edx; 1.56 @@ -484,6 +523,7 @@ int start_svm(void) 1.57 hvm_funcs.paging_enabled = svm_paging_enabled; 1.58 hvm_funcs.instruction_length = svm_instruction_length; 1.59 hvm_funcs.get_guest_ctrl_reg = svm_get_ctrl_reg; 1.60 + hvm_funcs.init_ap_context = svm_init_ap_context; 1.61 1.62 hvm_enabled = 1; 1.63 1.64 @@ -660,6 +700,20 @@ static void arch_svm_do_launch(struct vc 1.65 if (svm_dbg_on) 1.66 svm_dump_host_regs(__func__); 1.67 #endif 1.68 + if (v->vcpu_id != 0) 1.69 + { 1.70 + u16 cs_sel = regs->cs; 1.71 + /* 1.72 + * This is the launch of an AP; set state so that we begin executing 1.73 + * the trampoline code in real-mode. 1.74 + */ 1.75 + svm_do_vmmcall_reset_to_realmode(v, regs); 1.76 + /* Adjust the state to execute the trampoline code.*/ 1.77 + v->arch.hvm_svm.vmcb->rip = 0; 1.78 + v->arch.hvm_svm.vmcb->cs.sel= cs_sel; 1.79 + v->arch.hvm_svm.vmcb->cs.base = (cs_sel << 4); 1.80 + } 1.81 + 1.82 reset_stack_and_jump(svm_asm_do_launch); 1.83 } 1.84