Avoid stale pointer when moving domain to another cpupool When a domain is moved to another cpupool the scheduler private data pointers in vcpu and domain structures must never point to an already freed memory area. Signed-off-by: Juergen Gross diff -r 1d8c65aee03e xen/common/schedule.c --- a/xen/common/schedule.c Tue Feb 26 10:12:46 2013 +0000 +++ b/xen/common/schedule.c Wed Feb 27 07:16:05 2013 +0100 @@ -231,12 +231,14 @@ int sched_move_domain(struct domain *d, unsigned int new_p; void **vcpu_priv; void *domdata; + struct scheduler *old_ops; + void *old_domdata; domdata = SCHED_OP(c->sched, alloc_domdata, d); if ( domdata == NULL ) return -ENOMEM; - vcpu_priv = xzalloc_array(void *, d->max_vcpus); + vcpu_priv = xzalloc_array(void *, d->max_vcpus * 2); if ( vcpu_priv == NULL ) { SCHED_OP(c->sched, free_domdata, domdata); @@ -257,18 +259,18 @@ int sched_move_domain(struct domain *d, SCHED_OP(c->sched, free_domdata, domdata); return -ENOMEM; } + vcpu_priv[d->max_vcpus + v->vcpu_id] = v->sched_priv; } domain_pause(d); + old_ops = DOM2OP(d); + old_domdata = d->sched_priv; + for_each_vcpu ( d, v ) { SCHED_OP(VCPU2OP(v), remove_vcpu, v); - SCHED_OP(VCPU2OP(v), free_vdata, v->sched_priv); - v->sched_priv = NULL; } - - SCHED_OP(DOM2OP(d), free_domdata, d->sched_priv); d->cpupool = c; d->sched_priv = domdata; @@ -289,6 +291,13 @@ int sched_move_domain(struct domain *d, SCHED_OP(c->sched, insert_vcpu, v); } + + for_each_vcpu ( d, v ) + { + SCHED_OP(old_ops, free_vdata, vcpu_priv[d->max_vcpus + v->vcpu_id]); + } + + SCHED_OP(old_ops, free_domdata, old_domdata); domain_update_node_affinity(d);