/* Complete domain destroy after RCU readers are not holding old references. */ static void complete_domain_destroy(struct rcu_head *head) { struct domain *d = container_of(head, struct domain, rcu); struct vcpu *v; int i; for ( i = d->max_vcpus - 1; i >= 0; i-- ) { if ( (v = d->vcpu[i]) == NULL ) continue; tasklet_kill(&v->continue_hypercall_tasklet); vcpu_destroy(v); sched_destroy_vcpu(v); destroy_waitqueue_vcpu(v); } grant_table_destroy(d); arch_domain_destroy(d); watchdog_domain_destroy(d); rangeset_domain_destroy(d); cpupool_rm_domain(d); sched_destroy_domain(d); /* Free page used by xen oprofile buffer. */ free_xenoprof_pages(d); xfree(d->mem_event); for ( i = d->max_vcpus - 1; i >= 0; i-- ) if ( (v = d->vcpu[i]) != NULL ) free_vcpu_struct(v); if ( d->target != NULL ) put_domain(d->target); evtchn_destroy_final(d); xfree(d->pirq_mask); xfree(d->pirq_to_evtchn); xsm_free_security_domain(d); free_domain_struct(d); send_guest_global_virq(dom0, VIRQ_DOM_EXC); }
int vcpu_initialise(struct vcpu *v) { int rc = 0; BUILD_BUG_ON( sizeof(struct cpu_info) > STACK_SIZE ); v->arch.stack = alloc_xenheap_pages(STACK_ORDER, MEMF_node(vcpu_to_node(v))); if ( v->arch.stack == NULL ) return -ENOMEM; v->arch.cpu_info = (struct cpu_info *)(v->arch.stack + STACK_SIZE - sizeof(struct cpu_info)); memset(&v->arch.saved_context, 0, sizeof(v->arch.saved_context)); v->arch.saved_context.sp = (register_t)v->arch.cpu_info; v->arch.saved_context.pc = (register_t)continue_new_vcpu; /* Idle VCPUs don't need the rest of this setup */ if ( is_idle_vcpu(v) ) return rc; v->arch.sctlr = SCTLR_GUEST_INIT; /* * By default exposes an SMP system with AFF0 set to the VCPU ID * TODO: Handle multi-threading processor and cluster */ v->arch.vmpidr = MPIDR_SMP | (v->vcpu_id << MPIDR_AFF0_SHIFT); v->arch.actlr = READ_SYSREG32(ACTLR_EL1); processor_vcpu_initialise(v); if ( (rc = vcpu_vgic_init(v)) != 0 ) goto fail; if ( (rc = vcpu_vtimer_init(v)) != 0 ) goto fail; return rc; fail: vcpu_destroy(v); return rc; }
int vcpu_initialise(struct vcpu *v) { int rc = 0; BUILD_BUG_ON( sizeof(struct cpu_info) > STACK_SIZE ); v->arch.stack = alloc_xenheap_pages(STACK_ORDER, MEMF_node(vcpu_to_node(v))); if ( v->arch.stack == NULL ) return -ENOMEM; v->arch.cpu_info = (struct cpu_info *)(v->arch.stack + STACK_SIZE - sizeof(struct cpu_info)); memset(&v->arch.saved_context, 0, sizeof(v->arch.saved_context)); v->arch.saved_context.sp = (register_t)v->arch.cpu_info; v->arch.saved_context.pc = (register_t)continue_new_vcpu; /* Idle VCPUs don't need the rest of this setup */ if ( is_idle_vcpu(v) ) return rc; v->arch.sctlr = SCTLR_GUEST_INIT; v->arch.vmpidr = MPIDR_SMP | vcpuid_to_vaffinity(v->vcpu_id); v->arch.actlr = READ_SYSREG32(ACTLR_EL1); processor_vcpu_initialise(v); if ( (rc = vcpu_vgic_init(v)) != 0 ) goto fail; if ( (rc = vcpu_vtimer_init(v)) != 0 ) goto fail; return rc; fail: vcpu_destroy(v); return rc; }
void xh_vcpu_destroy(int vcpu) { assert(vm != NULL); vcpu_destroy(vm, vcpu); }