diff -r 859c8d66b203 xen/arch/x86/domain.c --- a/xen/arch/x86/domain.c Tue Feb 7 20:46:13 2006 +0000 +++ b/xen/arch/x86/domain.c Wed Feb 8 17:27:35 2006 +0800 @@ -807,6 +807,12 @@ return switch_required; } +void arch_vcpu_remove_affinity(struct vcpu *v, int new_processor) +{ + if (HVM_DOMAIN(v) && (v->arch.hvm_vmx.launch_cpu != new_processor)) + hvm_vcpu_remove_affinity(v, new_processor); +} + void sync_vcpu_execstate(struct vcpu *v) { if ( cpu_isset(smp_processor_id(), v->vcpu_dirty_cpumask) ) diff -r 859c8d66b203 xen/arch/x86/hvm/intercept.c --- a/xen/arch/x86/hvm/intercept.c Tue Feb 7 20:46:13 2006 +0000 +++ b/xen/arch/x86/hvm/intercept.c Wed Feb 8 17:27:35 2006 +0800 @@ -348,7 +348,7 @@ } /* hooks function for the PIT when the guest is active */ -static void pit_timer_fn(void *data) +void pit_timer_fn(void *data) { struct vcpu *v = data; struct hvm_virpit *vpit = &(v->domain->arch.hvm_domain.vpit); diff -r 859c8d66b203 xen/arch/x86/hvm/vmx/vmcs.c --- a/xen/arch/x86/hvm/vmx/vmcs.c Tue Feb 7 20:46:13 2006 +0000 +++ b/xen/arch/x86/hvm/vmx/vmcs.c Wed Feb 8 17:27:35 2006 +0800 @@ -167,6 +167,7 @@ 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); + error |= __vmwrite(HOST_RSP, (unsigned long)get_stack_bottom()); } static void vmx_do_launch(struct vcpu *v) @@ -212,7 +213,6 @@ shadow_direct_map_init(v); __vmwrite(GUEST_CR3, pagetable_get_paddr(v->domain->arch.phys_table)); __vmwrite(HOST_CR3, pagetable_get_paddr(v->arch.monitor_table)); - __vmwrite(HOST_RSP, (unsigned long)get_stack_bottom()); v->arch.schedule_tail = arch_vmx_do_resume; v->arch.hvm_vmx.launch_cpu = smp_processor_id(); @@ -500,6 +500,27 @@ __hvm_bug(guest_cpu_user_regs()); } +static void vmx_reinstall_timers(struct vcpu *v) +{ + struct hvm_virpit *vpit = &(v->domain->arch.hvm_domain.vpit); + + ASSERT(v->arch.arch_vmx.launch_cpu != smp_processor_id()); + + ASSERT(!active_timer(&vpit->pit_timer)); + ASSERT(!active_timer(&v->arch.hvm_vmx.hlt_timer)); + + /* vmx_do_resume will add pit_timer back */ + init_timer(&vpit->pit_timer, pit_timer_fn, v, v->processor); + + /* we dont need to set the hlt timer here */ + init_timer(&v->arch.hvm_vmx.hlt_timer, + hlt_timer_fn, v, v->processor); + + if (hvm_apic_support(v->domain) && VLAPIC(v)) + init_timer(&(VLAPIC(v))->vlapic_timer, vlapic_timer_fn, + VLAPIC(v), v->processor); +} + void arch_vmx_do_resume(struct vcpu *v) { if ( v->arch.hvm_vmx.launch_cpu == smp_processor_id() ) @@ -510,10 +531,10 @@ } else { - __vmpclear(virt_to_maddr(v->arch.hvm_vmx.vmcs)); load_vmcs(&v->arch.hvm_vmx, virt_to_maddr(v->arch.hvm_vmx.vmcs)); + vmx_set_host_env(v); + vmx_reinstall_timers(v); vmx_do_resume(v); - vmx_set_host_env(v); v->arch.hvm_vmx.launch_cpu = smp_processor_id(); reset_stack_and_jump(vmx_asm_do_relaunch); } diff -r 859c8d66b203 xen/arch/x86/hvm/vmx/vmx.c --- a/xen/arch/x86/hvm/vmx/vmx.c Tue Feb 7 20:46:13 2006 +0000 +++ b/xen/arch/x86/hvm/vmx/vmx.c Wed Feb 8 17:27:35 2006 +0800 @@ -79,6 +79,55 @@ } } +static inline void vmx_remove_timers(struct vcpu *v) +{ + struct hvm_virpit *vpit = &(v->domain->arch.hvm_domain.vpit); + + if (active_timer(&vpit->pit_timer)) + stop_timer(&(vpit->pit_timer)); + + if (active_timer(&v->arch.hvm_vmx.hlt_timer)) + stop_timer(&v->arch.hvm_vmx.hlt_timer); + + /* the local APIC timer should be coped like pit_timer in future */ + if ( hvm_apic_support(v->domain) && VLAPIC(v) && + active_timer(&(VLAPIC(v)->vlapic_timer))) + stop_timer(&(VLAPIC(v)->vlapic_timer)); +} + +static void vmx_smp_remove_affinity(void *info) +{ + struct vcpu *v = (struct vcpu *)info; + + ASSERT(HVM_DOMAIN(v)); + + if (v->arch.hvm_vmx.launch_cpu == smp_processor_id()) + { + vmx_remove_timers(v); + __vmpclear(virt_to_maddr(v->arch.hvm_vmx.vmcs)); + } +} + +static void vmx_request_clear_vmcs(struct vcpu *v) +{ + ASSERT(HVM_DOMAIN(v)); + + if (v->arch.hvm_vmx.launch_cpu == smp_processor_id()) + __vmpclear(virt_to_maddr(v->arch.hvm_vmx.vmcs)); + else + smp_call_function(vmx_smp_remove_affinity, v, 1, 1); +} + +static int vmx_vcpu_remove_affinity(struct vcpu *v, int new_processor) +{ + ASSERT(HVM_DOMAIN(v)); + + if (v->arch.hvm_vmx.launch_cpu != new_processor) + vmx_request_clear_vmcs(v); + + return 0; +} + void vmx_relinquish_resources(struct vcpu *v) { struct hvm_virpit *vpit; @@ -91,6 +140,7 @@ (void *)d->arch.hvm_domain.shared_page_va); } + vmx_request_clear_vmcs(v); destroy_vmcs(&v->arch.hvm_vmx); free_monitor_pagetable(v); vpit = &v->domain->arch.hvm_domain.vpit; @@ -505,7 +555,7 @@ hvm_funcs.initialize_guest_resources = vmx_initialize_guest_resources; hvm_funcs.relinquish_guest_resources = vmx_relinquish_guest_resources; - + hvm_funcs.vcpu_remove_affinity = vmx_vcpu_remove_affinity; hvm_funcs.store_cpu_guest_regs = vmx_store_cpu_guest_regs; hvm_funcs.load_cpu_guest_regs = vmx_load_cpu_guest_regs; diff -r 859c8d66b203 xen/common/sched_bvt.c --- a/xen/common/sched_bvt.c Tue Feb 7 20:46:13 2006 +0000 +++ b/xen/common/sched_bvt.c Wed Feb 8 17:27:35 2006 +0800 @@ -284,12 +284,16 @@ static int bvt_set_affinity(struct vcpu *v, cpumask_t *affinity) { + int new_processor; + if ( v == current ) return cpu_isset(v->processor, *affinity) ? 0 : -EBUSY; vcpu_pause(v); v->cpu_affinity = *affinity; - v->processor = first_cpu(v->cpu_affinity); + new_processor = first_cpu(v->cpu_affinity); + arch_vcpu_remove_affinity(v, new_processor); + v->processor = new_processor; EBVT_INFO(v)->migrated = 1; vcpu_unpause(v); diff -r 859c8d66b203 xen/common/sched_sedf.c --- a/xen/common/sched_sedf.c Tue Feb 7 20:46:13 2006 +0000 +++ b/xen/common/sched_sedf.c Wed Feb 8 17:27:35 2006 +0800 @@ -1391,12 +1391,16 @@ static int sedf_set_affinity(struct vcpu *v, cpumask_t *affinity) { + int new_processor; + if ( v == current ) return cpu_isset(v->processor, *affinity) ? 0 : -EBUSY; vcpu_pause(v); v->cpu_affinity = *affinity; - v->processor = first_cpu(v->cpu_affinity); + new_processor = first_cpu(v->cpu_affinity); + arch_vcpu_remove_affinity(v, new_processor); + v->processor = new_processor; vcpu_unpause(v); return 0; diff -r 859c8d66b203 xen/include/asm-x86/domain.h --- a/xen/include/asm-x86/domain.h Tue Feb 7 20:46:13 2006 +0000 +++ b/xen/include/asm-x86/domain.h Wed Feb 8 17:27:35 2006 +0800 @@ -170,6 +170,7 @@ #define hvm_vmx hvm_vcpu.u.vmx #define hvm_svm hvm_vcpu.u.svm +extern void arch_vcpu_remove_affinity(struct vcpu *v, int new_processor); #endif /* __ASM_DOMAIN_H__ */ /* diff -r 859c8d66b203 xen/include/asm-x86/hvm/hvm.h --- a/xen/include/asm-x86/hvm/hvm.h Tue Feb 7 20:46:13 2006 +0000 +++ b/xen/include/asm-x86/hvm/hvm.h Wed Feb 8 17:27:35 2006 +0800 @@ -37,7 +37,7 @@ */ int (*initialize_guest_resources)(struct vcpu *v); int (*relinquish_guest_resources)(struct vcpu *v); - + int (*vcpu_remove_affinity)(struct vcpu *v, int new_processor); /* * Store and load guest state: * 1) load/store guest register state, @@ -92,6 +92,14 @@ { if (hvm_funcs.relinquish_guest_resources) return hvm_funcs.relinquish_guest_resources(v); + return 0; +} + +static inline int +hvm_vcpu_remove_affinity(struct vcpu *v, int new_processor) +{ + if (hvm_funcs.vcpu_remove_affinity) + return hvm_funcs.vcpu_remove_affinity(v, new_processor); return 0; } diff -r 859c8d66b203 xen/include/asm-x86/hvm/io.h --- a/xen/include/asm-x86/hvm/io.h Tue Feb 7 20:46:13 2006 +0000 +++ b/xen/include/asm-x86/hvm/io.h Wed Feb 8 17:27:35 2006 +0800 @@ -152,6 +152,7 @@ extern void pic_irq_request(int *interrupt_request, int level); extern void hvm_pic_assist(struct vcpu *v); extern int cpu_get_interrupt(struct vcpu *v, int *type); +extern void pit_timer_fn(void *data); // XXX - think about this, maybe use bit 30 of the mfn to signify an MMIO frame. #define mmio_space(gpa) (!VALID_MFN(get_mfn_from_gpfn((gpa) >> PAGE_SHIFT))) diff -r 859c8d66b203 xen/include/asm-x86/hvm/vlapic.h --- a/xen/include/asm-x86/hvm/vlapic.h Tue Feb 7 20:46:13 2006 +0000 +++ b/xen/include/asm-x86/hvm/vlapic.h Wed Feb 8 17:27:35 2006 +0800 @@ -250,4 +250,5 @@ s_time_t get_apictime_scheduled(struct vcpu *v); int hvm_apic_support(struct domain *d); +extern void vlapic_timer_fn(void *data); #endif /* __ASM_X86_HVM_VLAPIC_H__ */