[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: [PATCH 2/2] xen/arm: vpl011: Fix domain_vpl011_init error path


  • To: Julien Grall <julien@xxxxxxx>, <xen-devel@xxxxxxxxxxxxxxxxxxxx>
  • From: Michal Orzel <michal.orzel@xxxxxxx>
  • Date: Thu, 23 Mar 2023 12:10:03 +0100
  • Arc-authentication-results: i=1; mx.microsoft.com 1; spf=pass (sender ip is 165.204.84.17) smtp.rcpttodomain=xen.org smtp.mailfrom=amd.com; dmarc=pass (p=quarantine sp=quarantine pct=100) action=none header.from=amd.com; dkim=none (message not signed); arc=none
  • Arc-message-signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=microsoft.com; s=arcselector9901; h=From:Date:Subject:Message-ID:Content-Type:MIME-Version:X-MS-Exchange-AntiSpam-MessageData-ChunkCount:X-MS-Exchange-AntiSpam-MessageData-0:X-MS-Exchange-AntiSpam-MessageData-1; bh=4widxbphHpArrB0F3pOKk8DifoAe5kxLKXEB+osPoG4=; b=TFM1yT8WIfIgDuN4lQruspOxS9THZ/7l3LMmZiWunHpDvcv1CSOQJNocjLsD9jOrs8yPuW58YYgX41TuSELW/dgJcPQQ8fQCnCHrdXkVDoVt+v8pcU/xj1Uwm7K3O9vo6PMQzNn4+KijVCXRocpk77r2NQGlJzQJXP21ZNt+5mwmY4D/sznrhe0kbNamIdegfu0pC4pEECj0wy7VAg/sfA5aSoBsYk9Wj32+AutuqMW5W1BpEh3UqwCLNi3fpb1aKv1hirJNbSyahsn1NJsYOgOIA0Q7dkN6IE3vOoO1bWHKxHcuTBbcuBZFP2KUXqpG63vhLrcxyG7V1RUMIKHvaw==
  • Arc-seal: i=1; a=rsa-sha256; s=arcselector9901; d=microsoft.com; cv=none; b=bosZ9MIGJc6dRrBpWwUY/MLPH6OHjC4aVRhFfva2357lP2/Ww0UQnWPDQpXAQQ2oMxfaUgYwD+LlAX98K8DG+hNHoYPNI/+AaoPjG5eeSez0X4cMw11Rf9UxCQWEtWxcdJ8RXEpYYOllZAYCShRXKInxoGRuLsjOm8bQwHQG22Xz9MY9nVNRj+gm86DGewRy1WGqyIDWKuLgN21j9xbg+ToFT165yFHqhTF7OlrfnUxzAPedrqiMGzXTBcR7aBQ6nzoDTsVQTdb0FJG3gnYJNS8CAjzj53FDIkTehb8vHPd0blGgqTeKB1zO8/xBiHX/EZJD0YUTuACmwb+H01/4oA==
  • Cc: Stefano Stabellini <sstabellini@xxxxxxxxxx>, Bertrand Marquis <bertrand.marquis@xxxxxxx>, Volodymyr Babchuk <Volodymyr_Babchuk@xxxxxxxx>
  • Delivery-date: Thu, 23 Mar 2023 11:10:27 +0000
  • List-id: Xen developer discussion <xen-devel.lists.xenproject.org>

Hi Julien,

On 22/03/2023 17:19, Julien Grall wrote:
> 
> 
> Hi Michal,
> 
> On 22/03/2023 10:29, Michal Orzel wrote:
>> When vgic_reserve_virq() fails and backend is in domain, we should also
>> free the allocated event channel.
>>
>> When backend is in Xen and call to xzalloc() returns NULL, there is no
>> need to call xfree(). This should be done instead on an error path
>> from vgic_reserve_virq().
> 
> Most likely this was implemented this way to avoid a double "if (
> vpl011->backend_in_domain)". TBH, I am not very thrilled with this
> approach. Could we instead consider to use domain_pl011_deinit()? (A
> couple of tweak would be necessary to use it)
I think we could. More about it later.

> 
>> Also, take the opportunity to return -ENOMEM
>> instead of -EINVAL when memory allocation fails.
>>
>> Fixes: 1ee1e4b0d1ff ("xen/arm: Allow vpl011 to be used by DomU")
>> Signed-off-by: Michal Orzel <michal.orzel@xxxxxxx>
>> ---
>>   xen/arch/arm/vpl011.c | 11 +++++++----
>>   1 file changed, 7 insertions(+), 4 deletions(-)
>>
>> diff --git a/xen/arch/arm/vpl011.c b/xen/arch/arm/vpl011.c
>> index 541ec962f189..df29a65ad365 100644
>> --- a/xen/arch/arm/vpl011.c
>> +++ b/xen/arch/arm/vpl011.c
>> @@ -696,8 +696,8 @@ int domain_vpl011_init(struct domain *d, struct 
>> vpl011_init_info *info)
>>           vpl011->backend.xen = xzalloc(struct vpl011_xen_backend);
>>           if ( vpl011->backend.xen == NULL )
>>           {
>> -            rc = -EINVAL;
>> -            goto out1;
>> +            rc = -ENOMEM;
>> +            goto out;
>>           }
>>       }
>>
>> @@ -720,12 +720,15 @@ int domain_vpl011_init(struct domain *d, struct 
>> vpl011_init_info *info)
>>   out2:
>>       vgic_free_virq(d, vpl011->virq);
>>
>> +    if ( vpl011->backend_in_domain )
>> +        free_xen_event_channel(d, vpl011->evtchn);
>> +    else
>> +        xfree(vpl011->backend.xen);
> 
> There is another bug here (unrelated to your change). You want to use
> XFREE() to avoid an extra free in domain_pl011_deinit(). Can you look at it?
Strictly speaking this is not a bug. Memory allocation can only happen if 
backend is in Xen.
This means, that if vpl011 init fails, we will call free only once 
(domain_vpl011_deinit
will not be called on this path i.e. we will invoke panic after construct_domU).
Of course, we could switch to XFREE just for sanity.

> 
>> +
>>   out1:
>>       if ( vpl011->backend_in_domain )
>>           destroy_ring_for_helper(&vpl011->backend.dom.ring_buf,
>>                                   vpl011->backend.dom.ring_page);
>> -    else
>> -        xfree(vpl011->backend.xen);
>>
>>   out:
>>       return rc;
> 
Solution to reuse domain_pl011_deinit would be as follows:

     vgic_free_virq(d, vpl011->virq);
 
 out1:
-    if ( vpl011->backend_in_domain )
-        destroy_ring_for_helper(&vpl011->backend.dom.ring_buf,
-                                vpl011->backend.dom.ring_page);
-    else
-        xfree(vpl011->backend.xen);
+    domain_vpl011_deinit(d);
 
 out:
     return rc;
@@ -737,12 +733,15 @@ void domain_vpl011_deinit(struct domain *d)
 
     if ( vpl011->backend_in_domain )
     {
-        if ( !vpl011->backend.dom.ring_buf )
-            return;
+        if ( vpl011->backend.dom.ring_buf )
+            destroy_ring_for_helper(&vpl011->backend.dom.ring_buf,
+                                    vpl011->backend.dom.ring_page);
 
-        free_xen_event_channel(d, vpl011->evtchn);
-        destroy_ring_for_helper(&vpl011->backend.dom.ring_buf,
-                                vpl011->backend.dom.ring_page);
+        if ( vpl011->evtchn )
+        {
+            free_xen_event_channel(d, vpl011->evtchn);
+            vpl011->evtchn = 0;
+        }
     }
     else
         xfree(vpl011->backend.xen);

However there is one problem with guarding free_xen_event_channel to be called 
only once.
Even without allocating event channel, vpl011->evtchn is 0 by default. So doing:
if ( is_port_valid(vpl011->evtchn) )
    free_xen_event_channel(d, vpl011->evtchn);
would not help us as evtchn 0 is always there. So in my proposal I'm assuming 
(I think correctly)
that vpl011->evtchn cannot be 0 after successful evtchn allocation because 0 is 
"reserved".
But I might be wrong in which case I'm clueless how to do the proper check.

~Michal



 


Rackspace

Lists.xenproject.org is hosted with RackSpace, monitoring our
servers 24x7x365 and backed by RackSpace's Fanatical Support®.