direct-io.hg

changeset 6489:e4ad3feadd4e

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>
author adsharma@los-vmm.sc.intel.com
date Tue Aug 09 11:06:44 2005 -0800 (2005-08-09)
parents b370beb3e107
children 5b239652c912
files xen/arch/x86/domain.c xen/arch/x86/vmx_vmcs.c xen/arch/x86/x86_32/entry.S xen/arch/x86/x86_64/entry.S xen/include/asm-x86/vmx.h xen/include/asm-x86/vmx_vmcs.h
line diff
     1.1 --- a/xen/arch/x86/domain.c	Tue Aug 09 11:06:44 2005 -0800
     1.2 +++ b/xen/arch/x86/domain.c	Tue Aug 09 11:06:44 2005 -0800
     1.3 @@ -303,6 +303,7 @@ arch_migrate_cpu(struct vcpu *v, int new
     1.4      if ( VMX_DOMAIN(v) && (v->processor != newcpu) ){
     1.5          u64 vmcs_phys_ptr = (u64) virt_to_phys(v->arch.arch_vmx.vmcs);
     1.6          __vmpclear(vmcs_phys_ptr);
     1.7 +        v->arch.schedule_tail = arch_vmx_do_relaunch;
     1.8      }
     1.9  }
    1.10  
    1.11 @@ -327,6 +328,18 @@ void arch_vmx_do_launch(struct vcpu *v)
    1.12      reset_stack_and_jump(vmx_asm_do_launch);
    1.13  }
    1.14  
    1.15 +void arch_vmx_do_relaunch(struct vcpu *v)
    1.16 +{
    1.17 +    u64 vmcs_phys_ptr = (u64) virt_to_phys(v->arch.arch_vmx.vmcs);
    1.18 +
    1.19 +    load_vmcs(&v->arch.arch_vmx, vmcs_phys_ptr);
    1.20 +    vmx_do_resume(v);
    1.21 +    vmx_set_host_env(v);
    1.22 +    v->arch.schedule_tail = arch_vmx_do_resume;
    1.23 +
    1.24 +    reset_stack_and_jump(vmx_asm_do_relaunch);
    1.25 +}
    1.26 +
    1.27  static int vmx_final_setup_guest(
    1.28      struct vcpu *v, struct vcpu_guest_context *ctxt)
    1.29  {
     2.1 --- a/xen/arch/x86/vmx_vmcs.c	Tue Aug 09 11:06:44 2005 -0800
     2.2 +++ b/xen/arch/x86/vmx_vmcs.c	Tue Aug 09 11:06:44 2005 -0800
     2.3 @@ -198,7 +198,7 @@ void vmx_set_host_env(struct vcpu *v)
     2.4      host_env.idtr_limit = desc.size;
     2.5      host_env.idtr_base = desc.address;
     2.6      error |= __vmwrite(HOST_IDTR_BASE, host_env.idtr_base);
     2.7 - 
     2.8 +
     2.9      __asm__ __volatile__ ("sgdt  (%0) \n" :: "a"(&desc) : "memory");
    2.10      host_env.gdtr_limit = desc.size;
    2.11      host_env.gdtr_base = desc.address;
    2.12 @@ -210,7 +210,6 @@ void vmx_set_host_env(struct vcpu *v)
    2.13      host_env.tr_base = (unsigned long) &init_tss[cpu];
    2.14      error |= __vmwrite(HOST_TR_SELECTOR, host_env.tr_selector);
    2.15      error |= __vmwrite(HOST_TR_BASE, host_env.tr_base);
    2.16 -
    2.17  }
    2.18  
    2.19  void vmx_do_launch(struct vcpu *v) 
     3.1 --- a/xen/arch/x86/x86_32/entry.S	Tue Aug 09 11:06:44 2005 -0800
     3.2 +++ b/xen/arch/x86/x86_32/entry.S	Tue Aug 09 11:06:44 2005 -0800
     3.3 @@ -108,31 +108,26 @@
     3.4          pushl %ecx; \
     3.5          pushl %ebx;
     3.6  
     3.7 +#define VMX_RESTORE_ALL_NOSEGREGS   \
     3.8 +        popl %ebx;  \
     3.9 +        popl %ecx;  \
    3.10 +        popl %edx;  \
    3.11 +        popl %esi;  \
    3.12 +        popl %edi;  \
    3.13 +        popl %ebp;  \
    3.14 +        popl %eax;  \
    3.15 +        addl $(NR_SKIPPED_REGS*4), %esp
    3.16 +
    3.17  ENTRY(vmx_asm_vmexit_handler)
    3.18          /* selectors are restored/saved by VMX */
    3.19          VMX_SAVE_ALL_NOSEGREGS
    3.20          call vmx_vmexit_handler
    3.21          jmp vmx_asm_do_resume
    3.22  
    3.23 -ENTRY(vmx_asm_do_launch)
    3.24 -        popl %ebx
    3.25 -        popl %ecx
    3.26 -        popl %edx
    3.27 -        popl %esi
    3.28 -        popl %edi
    3.29 -        popl %ebp
    3.30 -        popl %eax
    3.31 -        addl $(NR_SKIPPED_REGS*4), %esp
    3.32 -        /* VMLUANCH */
    3.33 -        .byte 0x0f,0x01,0xc2
    3.34 -        pushf
    3.35 -        call vm_launch_fail
    3.36 -        hlt
    3.37 -        
    3.38 -        ALIGN
    3.39 -        
    3.40 -ENTRY(vmx_asm_do_resume)
    3.41 -vmx_test_all_events:
    3.42 +.macro vmx_asm_common launch initialized
    3.43 +1:
    3.44 +/* vmx_test_all_events */
    3.45 +        .if \initialized
    3.46          GET_CURRENT(%ebx)
    3.47  /*test_all_events:*/
    3.48          xorl %ecx,%ecx
    3.49 @@ -142,37 +137,52 @@ vmx_test_all_events:
    3.50          movl VCPU_processor(%ebx),%eax
    3.51          shl  $IRQSTAT_shift,%eax
    3.52          test %ecx,irq_stat(%eax,1)
    3.53 -        jnz  vmx_process_softirqs
    3.54 +        jnz 2f
    3.55  
    3.56 -vmx_restore_all_guest:
    3.57 +/* vmx_restore_all_guest */
    3.58          call load_cr2
    3.59 +        .endif
    3.60 +        VMX_RESTORE_ALL_NOSEGREGS
    3.61          /* 
    3.62           * Check if we are going back to VMX-based VM
    3.63           * By this time, all the setups in the VMCS must be complete.
    3.64           */
    3.65 -        popl %ebx
    3.66 -        popl %ecx
    3.67 -        popl %edx
    3.68 -        popl %esi
    3.69 -        popl %edi
    3.70 -        popl %ebp
    3.71 -        popl %eax
    3.72 -        addl $(NR_SKIPPED_REGS*4), %esp
    3.73 +        .if \launch
    3.74 +        /* VMLUANCH */
    3.75 +        .byte 0x0f,0x01,0xc2
    3.76 +        pushf
    3.77 +        call vm_launch_fail
    3.78 +        .else
    3.79          /* VMRESUME */
    3.80          .byte 0x0f,0x01,0xc3
    3.81          pushf
    3.82          call vm_resume_fail
    3.83 +        .endif
    3.84          /* Should never reach here */
    3.85          hlt
    3.86  
    3.87          ALIGN
    3.88 -vmx_process_softirqs:
    3.89 +        .if \initialized
    3.90 +2:
    3.91 +/* vmx_process_softirqs */
    3.92          sti       
    3.93          call do_softirq
    3.94 -        jmp  vmx_test_all_events
    3.95 +        jmp 1b
    3.96 +        ALIGN
    3.97 +        .endif
    3.98 +.endm
    3.99 +
   3.100 +ENTRY(vmx_asm_do_launch)
   3.101 +    vmx_asm_common 1 0
   3.102 +
   3.103 +ENTRY(vmx_asm_do_resume)
   3.104 +    vmx_asm_common 0 1
   3.105 +
   3.106 +ENTRY(vmx_asm_do_relaunch)
   3.107 +    vmx_asm_common 1 1
   3.108 +
   3.109  #endif
   3.110  
   3.111 -        ALIGN
   3.112  restore_all_guest:
   3.113          testl $X86_EFLAGS_VM,UREGS_eflags(%esp)
   3.114          jnz  restore_all_vm86
     4.1 --- a/xen/arch/x86/x86_64/entry.S	Tue Aug 09 11:06:44 2005 -0800
     4.2 +++ b/xen/arch/x86/x86_64/entry.S	Tue Aug 09 11:06:44 2005 -0800
     4.3 @@ -194,39 +194,34 @@ test_all_events:
     4.4          pushq %r14; \
     4.5          pushq %r15; \
     4.6  
     4.7 +#define VMX_RESTORE_ALL_NOSEGREGS \
     4.8 +        popq %r15; \
     4.9 +        popq %r14; \
    4.10 +        popq %r13; \
    4.11 +        popq %r12; \
    4.12 +        popq %rbp; \
    4.13 +        popq %rbx; \
    4.14 +        popq %r11; \
    4.15 +        popq %r10; \
    4.16 +        popq %r9;  \
    4.17 +        popq %r8;  \
    4.18 +        popq %rax; \
    4.19 +        popq %rcx; \
    4.20 +        popq %rdx; \
    4.21 +        popq %rsi; \
    4.22 +        popq %rdi; \
    4.23 +        addq $(NR_SKIPPED_REGS*8), %rsp; \
    4.24 +
    4.25  ENTRY(vmx_asm_vmexit_handler)
    4.26          /* selectors are restored/saved by VMX */
    4.27          VMX_SAVE_ALL_NOSEGREGS
    4.28          call vmx_vmexit_handler
    4.29          jmp vmx_asm_do_resume
    4.30  
    4.31 -ENTRY(vmx_asm_do_launch)
    4.32 -        popq %r15
    4.33 -        popq %r14
    4.34 -        popq %r13
    4.35 -        popq %r12
    4.36 -        popq %rbp
    4.37 -        popq %rbx
    4.38 -        popq %r11
    4.39 -        popq %r10
    4.40 -        popq %r9
    4.41 -        popq %r8
    4.42 -        popq %rax
    4.43 -        popq %rcx
    4.44 -        popq %rdx
    4.45 -        popq %rsi
    4.46 -        popq %rdi
    4.47 -        addq $(NR_SKIPPED_REGS*8), %rsp
    4.48 -        /* VMLUANCH */
    4.49 -        .byte 0x0f,0x01,0xc2
    4.50 -        pushfq
    4.51 -        call vm_launch_fail
    4.52 -        hlt
    4.53 -        
    4.54 -        ALIGN
    4.55 -        
    4.56 -ENTRY(vmx_asm_do_resume)
    4.57 -vmx_test_all_events:
    4.58 +.macro vmx_asm_common launch initialized 
    4.59 +1:
    4.60 +        .if \initialized
    4.61 +/* vmx_test_all_events */
    4.62          GET_CURRENT(%rbx)
    4.63  /* test_all_events: */
    4.64          cli                             # tests must not race interrupts
    4.65 @@ -235,42 +230,51 @@ vmx_test_all_events:
    4.66          shl   $IRQSTAT_shift,%rax
    4.67          leaq  irq_stat(%rip), %rdx
    4.68          testl $~0,(%rdx,%rax,1)
    4.69 -        jnz   vmx_process_softirqs
    4.70 +        jnz  2f 
    4.71  
    4.72 -vmx_restore_all_guest:
    4.73 +/* vmx_restore_all_guest */
    4.74          call load_cr2
    4.75 +        .endif
    4.76          /* 
    4.77           * Check if we are going back to VMX-based VM
    4.78           * By this time, all the setups in the VMCS must be complete.
    4.79           */
    4.80 -        popq %r15
    4.81 -        popq %r14
    4.82 -        popq %r13
    4.83 -        popq %r12
    4.84 -        popq %rbp
    4.85 -        popq %rbx
    4.86 -        popq %r11
    4.87 -        popq %r10
    4.88 -        popq %r9
    4.89 -        popq %r8
    4.90 -        popq %rax
    4.91 -        popq %rcx
    4.92 -        popq %rdx
    4.93 -        popq %rsi
    4.94 -        popq %rdi
    4.95 -        addq $(NR_SKIPPED_REGS*8), %rsp
    4.96 +        VMX_RESTORE_ALL_NOSEGREGS
    4.97 +        .if \launch
    4.98 +        /* VMLUANCH */
    4.99 +        .byte 0x0f,0x01,0xc2
   4.100 +        pushfq
   4.101 +        call vm_launch_fail
   4.102 +        .else
   4.103          /* VMRESUME */
   4.104          .byte 0x0f,0x01,0xc3
   4.105          pushfq
   4.106          call vm_resume_fail
   4.107 +        .endif
   4.108          /* Should never reach here */
   4.109          hlt
   4.110  
   4.111          ALIGN
   4.112 -vmx_process_softirqs:
   4.113 +
   4.114 +        .if \initialized
   4.115 +2:
   4.116 +/* vmx_process_softirqs */
   4.117          sti       
   4.118          call do_softirq
   4.119 -        jmp  vmx_test_all_events
   4.120 +        jmp 1b
   4.121 +        ALIGN
   4.122 +        .endif
   4.123 +.endm
   4.124 +
   4.125 +ENTRY(vmx_asm_do_launch)
   4.126 +      vmx_asm_common 1 0
   4.127 +
   4.128 +ENTRY(vmx_asm_do_resume)
   4.129 +      vmx_asm_common 0 1
   4.130 +
   4.131 +ENTRY(vmx_asm_do_relaunch)
   4.132 +      vmx_asm_common 1 1
   4.133 +
   4.134  #endif
   4.135  
   4.136          ALIGN
     5.1 --- a/xen/include/asm-x86/vmx.h	Tue Aug 09 11:06:44 2005 -0800
     5.2 +++ b/xen/include/asm-x86/vmx.h	Tue Aug 09 11:06:44 2005 -0800
     5.3 @@ -35,6 +35,7 @@ extern void vmx_intr_assist(struct vcpu 
     5.4  
     5.5  extern void arch_vmx_do_launch(struct vcpu *);
     5.6  extern void arch_vmx_do_resume(struct vcpu *);
     5.7 +extern void arch_vmx_do_relaunch(struct vcpu *);
     5.8  
     5.9  extern int vmcs_size;
    5.10  extern unsigned int cpu_rev;
     6.1 --- a/xen/include/asm-x86/vmx_vmcs.h	Tue Aug 09 11:06:44 2005 -0800
     6.2 +++ b/xen/include/asm-x86/vmx_vmcs.h	Tue Aug 09 11:06:44 2005 -0800
     6.3 @@ -93,6 +93,7 @@ struct arch_vmx_struct {
     6.4  
     6.5  void vmx_do_launch(struct vcpu *); 
     6.6  void vmx_do_resume(struct vcpu *); 
     6.7 +void vmx_set_host_env(struct vcpu *);
     6.8  
     6.9  struct vmcs_struct *alloc_vmcs(void);
    6.10  void free_vmcs(struct vmcs_struct *);