Support VCPU migration Reorganize the low level asm code to support relaunching a VMCS on a different logical CPU. Signed-off-by: Yunhong Jiang <yunhong.jiang@intel.com> Signed-off-by: Arun Sharma <arun.sharma@intel.com> diff -r b370beb3e107 -r e4ad3feadd4e xen/arch/x86/domain.c --- a/xen/arch/x86/domain.c Tue Aug 9 19:06:44 2005 +++ b/xen/arch/x86/domain.c Tue Aug 9 19:06:44 2005 @@ -303,6 +303,7 @@ if ( VMX_DOMAIN(v) && (v->processor != newcpu) ){ u64 vmcs_phys_ptr = (u64) virt_to_phys(v->arch.arch_vmx.vmcs); __vmpclear(vmcs_phys_ptr); + v->arch.schedule_tail = arch_vmx_do_relaunch; } } @@ -325,6 +326,18 @@ load_vmcs(&v->arch.arch_vmx, vmcs_phys_ptr); vmx_do_launch(v); reset_stack_and_jump(vmx_asm_do_launch); +} + +void arch_vmx_do_relaunch(struct vcpu *v) +{ + u64 vmcs_phys_ptr = (u64) virt_to_phys(v->arch.arch_vmx.vmcs); + + load_vmcs(&v->arch.arch_vmx, vmcs_phys_ptr); + vmx_do_resume(v); + vmx_set_host_env(v); + v->arch.schedule_tail = arch_vmx_do_resume; + + reset_stack_and_jump(vmx_asm_do_relaunch); } static int vmx_final_setup_guest( diff -r b370beb3e107 -r e4ad3feadd4e xen/arch/x86/vmx_vmcs.c --- a/xen/arch/x86/vmx_vmcs.c Tue Aug 9 19:06:44 2005 +++ b/xen/arch/x86/vmx_vmcs.c Tue Aug 9 19:06:44 2005 @@ -198,7 +198,7 @@ host_env.idtr_limit = desc.size; host_env.idtr_base = desc.address; error |= __vmwrite(HOST_IDTR_BASE, host_env.idtr_base); - + __asm__ __volatile__ ("sgdt (%0) \n" :: "a"(&desc) : "memory"); host_env.gdtr_limit = desc.size; host_env.gdtr_base = desc.address; @@ -210,7 +210,6 @@ host_env.tr_base = (unsigned long) &init_tss[cpu]; error |= __vmwrite(HOST_TR_SELECTOR, host_env.tr_selector); error |= __vmwrite(HOST_TR_BASE, host_env.tr_base); - } void vmx_do_launch(struct vcpu *v) diff -r b370beb3e107 -r e4ad3feadd4e xen/arch/x86/x86_32/entry.S --- a/xen/arch/x86/x86_32/entry.S Tue Aug 9 19:06:44 2005 +++ b/xen/arch/x86/x86_32/entry.S Tue Aug 9 19:06:44 2005 @@ -108,31 +108,26 @@ pushl %ecx; \ pushl %ebx; +#define VMX_RESTORE_ALL_NOSEGREGS \ + popl %ebx; \ + popl %ecx; \ + popl %edx; \ + popl %esi; \ + popl %edi; \ + popl %ebp; \ + popl %eax; \ + addl $(NR_SKIPPED_REGS*4), %esp + ENTRY(vmx_asm_vmexit_handler) /* selectors are restored/saved by VMX */ VMX_SAVE_ALL_NOSEGREGS call vmx_vmexit_handler jmp vmx_asm_do_resume -ENTRY(vmx_asm_do_launch) - popl %ebx - popl %ecx - popl %edx - popl %esi - popl %edi - popl %ebp - popl %eax - addl $(NR_SKIPPED_REGS*4), %esp - /* VMLUANCH */ - .byte 0x0f,0x01,0xc2 - pushf - call vm_launch_fail - hlt - - ALIGN - -ENTRY(vmx_asm_do_resume) -vmx_test_all_events: +.macro vmx_asm_common launch initialized +1: +/* vmx_test_all_events */ + .if \initialized GET_CURRENT(%ebx) /*test_all_events:*/ xorl %ecx,%ecx @@ -142,37 +137,52 @@ movl VCPU_processor(%ebx),%eax shl $IRQSTAT_shift,%eax test %ecx,irq_stat(%eax,1) - jnz vmx_process_softirqs - -vmx_restore_all_guest: + jnz 2f + +/* vmx_restore_all_guest */ call load_cr2 + .endif + VMX_RESTORE_ALL_NOSEGREGS /* * Check if we are going back to VMX-based VM * By this time, all the setups in the VMCS must be complete. */ - popl %ebx - popl %ecx - popl %edx - popl %esi - popl %edi - popl %ebp - popl %eax - addl $(NR_SKIPPED_REGS*4), %esp + .if \launch + /* VMLUANCH */ + .byte 0x0f,0x01,0xc2 + pushf + call vm_launch_fail + .else /* VMRESUME */ .byte 0x0f,0x01,0xc3 pushf call vm_resume_fail + .endif /* Should never reach here */ hlt ALIGN -vmx_process_softirqs: + .if \initialized +2: +/* vmx_process_softirqs */ sti call do_softirq - jmp vmx_test_all_events + jmp 1b + ALIGN + .endif +.endm + +ENTRY(vmx_asm_do_launch) + vmx_asm_common 1 0 + +ENTRY(vmx_asm_do_resume) + vmx_asm_common 0 1 + +ENTRY(vmx_asm_do_relaunch) + vmx_asm_common 1 1 + #endif - ALIGN restore_all_guest: testl $X86_EFLAGS_VM,UREGS_eflags(%esp) jnz restore_all_vm86 diff -r b370beb3e107 -r e4ad3feadd4e xen/arch/x86/x86_64/entry.S --- a/xen/arch/x86/x86_64/entry.S Tue Aug 9 19:06:44 2005 +++ b/xen/arch/x86/x86_64/entry.S Tue Aug 9 19:06:44 2005 @@ -194,39 +194,34 @@ pushq %r14; \ pushq %r15; \ +#define VMX_RESTORE_ALL_NOSEGREGS \ + popq %r15; \ + popq %r14; \ + popq %r13; \ + popq %r12; \ + popq %rbp; \ + popq %rbx; \ + popq %r11; \ + popq %r10; \ + popq %r9; \ + popq %r8; \ + popq %rax; \ + popq %rcx; \ + popq %rdx; \ + popq %rsi; \ + popq %rdi; \ + addq $(NR_SKIPPED_REGS*8), %rsp; \ + ENTRY(vmx_asm_vmexit_handler) /* selectors are restored/saved by VMX */ VMX_SAVE_ALL_NOSEGREGS call vmx_vmexit_handler jmp vmx_asm_do_resume -ENTRY(vmx_asm_do_launch) - popq %r15 - popq %r14 - popq %r13 - popq %r12 - popq %rbp - popq %rbx - popq %r11 - popq %r10 - popq %r9 - popq %r8 - popq %rax - popq %rcx - popq %rdx - popq %rsi - popq %rdi - addq $(NR_SKIPPED_REGS*8), %rsp - /* VMLUANCH */ - .byte 0x0f,0x01,0xc2 - pushfq - call vm_launch_fail - hlt - - ALIGN - -ENTRY(vmx_asm_do_resume) -vmx_test_all_events: +.macro vmx_asm_common launch initialized +1: + .if \initialized +/* vmx_test_all_events */ GET_CURRENT(%rbx) /* test_all_events: */ cli # tests must not race interrupts @@ -235,42 +230,51 @@ shl $IRQSTAT_shift,%rax leaq irq_stat(%rip), %rdx testl $~0,(%rdx,%rax,1) - jnz vmx_process_softirqs - -vmx_restore_all_guest: + jnz 2f + +/* vmx_restore_all_guest */ call load_cr2 + .endif /* * Check if we are going back to VMX-based VM * By this time, all the setups in the VMCS must be complete. */ - popq %r15 - popq %r14 - popq %r13 - popq %r12 - popq %rbp - popq %rbx - popq %r11 - popq %r10 - popq %r9 - popq %r8 - popq %rax - popq %rcx - popq %rdx - popq %rsi - popq %rdi - addq $(NR_SKIPPED_REGS*8), %rsp + VMX_RESTORE_ALL_NOSEGREGS + .if \launch + /* VMLUANCH */ + .byte 0x0f,0x01,0xc2 + pushfq + call vm_launch_fail + .else /* VMRESUME */ .byte 0x0f,0x01,0xc3 pushfq call vm_resume_fail + .endif /* Should never reach here */ hlt ALIGN -vmx_process_softirqs: + + .if \initialized +2: +/* vmx_process_softirqs */ sti call do_softirq - jmp vmx_test_all_events + jmp 1b + ALIGN + .endif +.endm + +ENTRY(vmx_asm_do_launch) + vmx_asm_common 1 0 + +ENTRY(vmx_asm_do_resume) + vmx_asm_common 0 1 + +ENTRY(vmx_asm_do_relaunch) + vmx_asm_common 1 1 + #endif ALIGN diff -r b370beb3e107 -r e4ad3feadd4e xen/include/asm-x86/vmx.h --- a/xen/include/asm-x86/vmx.h Tue Aug 9 19:06:44 2005 +++ b/xen/include/asm-x86/vmx.h Tue Aug 9 19:06:44 2005 @@ -35,6 +35,7 @@ extern void arch_vmx_do_launch(struct vcpu *); extern void arch_vmx_do_resume(struct vcpu *); +extern void arch_vmx_do_relaunch(struct vcpu *); extern int vmcs_size; extern unsigned int cpu_rev; diff -r b370beb3e107 -r e4ad3feadd4e xen/include/asm-x86/vmx_vmcs.h --- a/xen/include/asm-x86/vmx_vmcs.h Tue Aug 9 19:06:44 2005 +++ b/xen/include/asm-x86/vmx_vmcs.h Tue Aug 9 19:06:44 2005 @@ -93,6 +93,7 @@ void vmx_do_launch(struct vcpu *); void vmx_do_resume(struct vcpu *); +void vmx_set_host_env(struct vcpu *); struct vmcs_struct *alloc_vmcs(void); void free_vmcs(struct vmcs_struct *); _______________________________________________ Xen-devel mailing list Xen-devel@lists.xensource.com http://lists.xensource.com/xen-devel