mirror of
https://github.com/xen-project/xen.git
synced 2026-10-28 10:11:27 +01:00
sched/null: avoid crash after failed domU creation
When creating a domU, but the creation fails, there is a corner case that may lead to a crash in the null scheduler when running a debug build of Xen. (XEN) **************************************** (XEN) Panic on CPU 0: (XEN) Assertion 'npc->unit == unit' failed at common/sched/null.c:379 (XEN) **************************************** The events leading to the crash are: * null_unit_insert() was invoked with the unit offline. Since the unit was offline, unit_assign() was not called, and null_unit_insert() returned. * Later during domain creation, the unit was onlined * Eventually, domain creation failed due to bad configuration * null_unit_remove() was invoked with the unit still online. Since the unit was online, it called unit_deassign() and triggered an ASSERT. To fix this, only call unit_deassign() when npc->unit is non-NULL in null_unit_remove. Signed-off-by: Stewart Hildebrand <stewart.hildebrand@amd.com> Reviewed-by: Juergen Gross <jgross@suse.com> Acked-by: Dario Faggioli <dfaggioli@suse.com>
This commit is contained in:
1 parent
569df1847c
commit
c2eae2614c
1 file changed
+6
-3
@@ -522,6 +522,8 @@ static void cf_check null_unit_remove(
|
||||
{
|
||||
struct null_private *prv = null_priv(ops);
|
||||
struct null_unit *nvc = null_unit(unit);
|
||||
struct null_pcpu *npc;
|
||||
unsigned int cpu;
|
||||
spinlock_t *lock;
|
||||
|
||||
ASSERT(!is_idle_unit(unit));
|
||||
@@ -531,8 +533,6 @@ static void cf_check null_unit_remove(
|
||||
/* If offline, the unit shouldn't be assigned, nor in the waitqueue */
|
||||
if ( unlikely(!is_unit_online(unit)) )
|
||||
{
|
||||
struct null_pcpu *npc;
|
||||
|
||||
npc = unit->res->sched_priv;
|
||||
ASSERT(npc->unit != unit);
|
||||
ASSERT(list_empty(&nvc->waitq_elem));
|
||||
@@ -549,7 +549,10 @@ static void cf_check null_unit_remove(
|
||||
goto out;
|
||||
}
|
||||
|
||||
unit_deassign(prv, unit);
|
||||
cpu = sched_unit_master(unit);
|
||||
npc = get_sched_res(cpu)->sched_priv;
|
||||
if ( npc->unit )
|
||||
unit_deassign(prv, unit);
|
||||
|
||||
out:
|
||||
unit_schedule_unlock_irq(lock, unit);
|
||||
|
||||