diff options
Diffstat (limited to 'xen/common')
-rw-r--r-- | xen/common/dom0_ops.c | 4 | ||||
-rw-r--r-- | xen/common/domain.c | 35 | ||||
-rw-r--r-- | xen/common/network.c | 6 |
3 files changed, 27 insertions, 18 deletions
diff --git a/xen/common/dom0_ops.c b/xen/common/dom0_ops.c index 1d43f641ba..e451a8f3e7 100644 --- a/xen/common/dom0_ops.c +++ b/xen/common/dom0_ops.c @@ -81,6 +81,7 @@ long do_dom0_op(dom0_op_t *u_dom0_op) wake_up(p); reschedule(p); ret = p->domain; + free_task_struct(p); } break; @@ -113,13 +114,14 @@ long do_dom0_op(dom0_op_t *u_dom0_op) case DOM0_KILLDOMAIN: { unsigned int dom = op.u.killdomain.domain; + int force = op.u.killdomain.force; if ( dom == IDLE_DOMAIN_ID ) { ret = -EPERM; } else { - ret = kill_other_domain(dom); + ret = kill_other_domain(dom, force); } } break; diff --git a/xen/common/domain.c b/xen/common/domain.c index 5e862ada6d..89efe59f64 100644 --- a/xen/common/domain.c +++ b/xen/common/domain.c @@ -40,6 +40,8 @@ struct task_struct *do_newdomain(unsigned int dom_id, unsigned int cpu) if (!p) goto newdomain_out; memset(p, 0, sizeof(*p)); + atomic_set(&p->refcnt, 1); + p->domain = dom_id; p->processor = cpu; @@ -82,6 +84,7 @@ struct task_struct *find_domain_by_id(unsigned int dom) read_lock_irq(&tasklist_lock); do { if ( (p->domain == dom) ) { + get_task_struct(p); /* increment the refcnt for caller */ read_unlock_irq(&tasklist_lock); return (p); } @@ -117,27 +120,27 @@ void kill_domain(void) } -long kill_other_domain(unsigned int dom) +long kill_other_domain(unsigned int dom, int force) { - struct task_struct *p = &idle0_task; + struct task_struct *p; unsigned long cpu_mask = 0; - long ret = -ESRCH; - read_lock_irq(&tasklist_lock); - do { - if ( p->domain == dom ) - { - cpu_mask = mark_guest_event(p, _EVENT_DIE); - ret = 0; - break; - } - } - while ( (p = p->next_task) != &idle0_task ); - read_unlock_irq(&tasklist_lock); + p = find_domain_by_id(dom); + if ( p == NULL ) return -ESRCH; - hyp_event_notify(cpu_mask); + if ( force ) + { + cpu_mask = mark_hyp_event(p, _HYP_EVENT_DIE); + hyp_event_notify(cpu_mask); + } + else + { + cpu_mask = mark_guest_event(p, _EVENT_DIE); + guest_event_notify(cpu_mask); + } - return ret; + free_task_struct(p); + return 0; } diff --git a/xen/common/network.c b/xen/common/network.c index f761ca9ba2..cd726621f1 100644 --- a/xen/common/network.c +++ b/xen/common/network.c @@ -81,7 +81,7 @@ net_vif_t *create_net_vif(int domain) new_vif->net_ring = new_ring; new_vif->shadow_ring = shadow_ring; - new_vif->domain = find_domain_by_id(domain); + new_vif->domain = dom_task; new_vif->list.next = NULL; @@ -93,6 +93,7 @@ net_vif_t *create_net_vif(int domain) dom_task->net_vif_list[dom_task->num_net_vifs] = new_vif; dom_task->num_net_vifs++; + free_task_struct(dom_task); return new_vif; fail: @@ -103,6 +104,8 @@ fail: if ( shadow_ring->tx_ring ) kfree(shadow_ring->tx_ring); kfree(shadow_ring); } + + free_task_struct(dom_task); return NULL; } @@ -149,6 +152,7 @@ void vif_query(vif_query_t *vq) copy_to_user(vq->buf, buf, strlen(buf) + 1); + free_task_struct(dom_task); } |