aboutsummaryrefslogtreecommitdiffstats
path: root/xen/common
diff options
context:
space:
mode:
Diffstat (limited to 'xen/common')
-rw-r--r--xen/common/dom0_ops.c4
-rw-r--r--xen/common/domain.c35
-rw-r--r--xen/common/network.c6
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);
}