xen/arm: vcpu: Correctly release resources when a VCPU fails to initialize
authorJulien Grall <julien.grall@linaro.org>
Wed, 30 Apr 2014 19:15:55 +0000 (20:15 +0100)
committerIan Campbell <ian.campbell@citrix.com>
Mon, 2 Jun 2014 13:38:12 +0000 (14:38 +0100)
While I was adding new failing code at the end of the function, I noticed
that the vtimers are not freed which messes up all the timers and will crash
Xen quickly when the page s reused.

Currently neither vcpu_vgic_init nor vcpu_vtimer_init fails, so we
are safe for now. With the new GICv3 code, the former function will be able
to fail. This will result in a memory leak.

Call vcpu_destroy if the initialization has failed. We also need to add a
boolean to know if the vtimers are correctly setup as the timer common code
doesn't have any safeguard against removing a non-initialized timer.

Signed-off-by: Julien Grall <julien.grall@linaro.org>
Acked-by: Ian Campbell <ian.campbell@citrix.com>
xen/arch/arm/domain.c
xen/arch/arm/vtimer.c
xen/include/asm-arm/domain.h

index 2ae6941a63f93020cb1d6edeceeec9c8f3272887..04d0cd0347b8346ea39cab0bcbe14d86310be44b 100644 (file)
@@ -470,12 +470,16 @@ int vcpu_initialise(struct vcpu *v)
     processor_vcpu_initialise(v);
 
     if ( (rc = vcpu_vgic_init(v)) != 0 )
-        return rc;
+        goto fail;
 
     if ( (rc = vcpu_vtimer_init(v)) != 0 )
-        return rc;
+        goto fail;
 
     return rc;
+
+fail:
+    vcpu_destroy(v);
+    return rc;
 }
 
 void vcpu_destroy(struct vcpu *v)
index b93153ea758949dbc25a6062cf649383668a5dff..7b50826fb529c9325f065d29c0a2f81773ce0da5 100644 (file)
@@ -77,11 +77,16 @@ int vcpu_vtimer_init(struct vcpu *v)
         : GUEST_TIMER_VIRT_PPI;
     t->v = v;
 
+    v->arch.vtimer_initialized = 1;
+
     return 0;
 }
 
 void vcpu_timer_destroy(struct vcpu *v)
 {
+    if ( !v->arch.vtimer_initialized )
+        return;
+
     kill_timer(&v->arch.virt_timer.timer);
     kill_timer(&v->arch.phys_timer.timer);
 }
index b29692320a36cff8d79bd793ec07463277612c49..f6cb1c03d7991d75d69a6c570c7da1e208cd32bf 100644 (file)
@@ -289,6 +289,7 @@ struct arch_vcpu
 
     struct vtimer phys_timer;
     struct vtimer virt_timer;
+    bool_t vtimer_initialized;
 }  __cacheline_aligned;
 
 void vcpu_show_execution_state(struct vcpu *);