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

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


  • To: <xen-devel@xxxxxxxxxxxxxxxxxxxx>
  • From: Michal Orzel <michal.orzel@xxxxxxx>
  • Date: Thu, 23 Mar 2023 14:56:36 +0100
  • Arc-authentication-results: i=1; mx.microsoft.com 1; spf=pass (sender ip is 165.204.84.17) smtp.rcpttodomain=lists.xenproject.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=ToounznfMNd5yVA96KMkq0Sokt6TSD7jFIpRIWRezZI=; b=OT9509P6Q4cTgZ9XqiKm8R8mt7vFyeBB/fq4sdqXaHvMJBqr2eK9OM8FQBBygqPy51x/E71Z+9fQbx5lL98YPv89uGpm77aFKt7Jo3U+SbsdjdbSK4n+JA17W4d2I9U+DpHYnJhBNAnuKRnjjY3IvMKzEkURoju0bAYj+rfhl+9p1tVRSjR2GwsCfAVr71oFQ1kOcsJTdh5kwcYYRZDio95Y/R/XiFHnQRbhA+ozb8OAuMhK53opVnYcPY18pvNOW2/TTzLbxO5ogi0xSOCTq/ShjKoH/nFX8QQkYMssirou8tpEdzW/9FRwTBLSsyoBqFIickz3rPI66wGlXd95Ww==
  • Arc-seal: i=1; a=rsa-sha256; s=arcselector9901; d=microsoft.com; cv=none; b=hXpOGdMrazuz1ETuqXe+hhMDpaK4iKvmBp1fglZgwV6ErdVxEr7NA2LXHbH2yY/xLAQUjqNTv4IWNMetHO7ktY1b6MHZjEMuUtIzONetqidmmuc0zf5w0q0V6xGh3GW2YJ7qvOUlaDfcqWzwBeVWiqvuC9OA4DCq/BtQj5+YrBqxNc/SKb+DIGadgrDvdOOgL1sROofBkpsI/JprA1CFU0nkiVkCaN40iZsiXvosH4ykMsqTDhW4X+vldC5/U2Yq1wW8iX0osTOZ8yF6BWk1Dor2iU+zeshEYmPC3NyYHihNd+lfixET7Wz4Iuv3i0To/zgG+LFV3Rh6PDxvjQbzGA==
  • Cc: Michal Orzel <michal.orzel@xxxxxxx>, Stefano Stabellini <sstabellini@xxxxxxxxxx>, Julien Grall <julien@xxxxxxx>, Bertrand Marquis <bertrand.marquis@xxxxxxx>, Volodymyr Babchuk <Volodymyr_Babchuk@xxxxxxxx>
  • Delivery-date: Thu, 23 Mar 2023 13:57:15 +0000
  • List-id: Xen developer discussion <xen-devel.lists.xenproject.org>

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(). Moreover, we should be calling XFREE() to
prevent an extra free in domain_vpl011_deinit().

In order not to repeat the same steps twice, call domain_vpl011_deinit()
on an error path whenever there is more work to do than returning rc.
Since this function can now be called from different places and more
than once, add proper guards, use XFREE() instead of xfree() and move
vgic_free_virq() to it.

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>
---
Changes in v2:
 - make use of domain_vpl011_deinit() to prevent code duplication
 - use XFREE() instead of xfree()
---
 xen/arch/arm/vpl011.c | 47 +++++++++++++++++++++++++++----------------
 1 file changed, 30 insertions(+), 17 deletions(-)

diff --git a/xen/arch/arm/vpl011.c b/xen/arch/arm/vpl011.c
index 541ec962f189..2fa80bc15ac4 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;
         }
     }
 
@@ -705,7 +705,7 @@ int domain_vpl011_init(struct domain *d, struct 
vpl011_init_info *info)
     if ( !rc )
     {
         rc = -EINVAL;
-        goto out2;
+        goto out1;
     }
 
     vpl011->uartfr = TXFE | RXFE;
@@ -717,15 +717,8 @@ int domain_vpl011_init(struct domain *d, struct 
vpl011_init_info *info)
 
     return 0;
 
-out2:
-    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;
@@ -735,17 +728,37 @@ void domain_vpl011_deinit(struct domain *d)
 {
     struct vpl011 *vpl011 = &d->arch.vpl011;
 
+    if ( vpl011->virq )
+    {
+        vgic_free_virq(d, vpl011->virq);
+
+        /*
+         * Set to invalid irq (we use SPI) to prevent extra free and to avoid
+         * freeing irq that could have already been reserved by someone else.
+         */
+        vpl011->virq = 0;
+    }
+
     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);
+
+        if ( vpl011->evtchn )
+        {
+            free_xen_event_channel(d, vpl011->evtchn);
 
-        free_xen_event_channel(d, vpl011->evtchn);
-        destroy_ring_for_helper(&vpl011->backend.dom.ring_buf,
-                                vpl011->backend.dom.ring_page);
+            /*
+             * Set to invalid event channel port to prevent extra free and to
+             * avoid freeing port that could have already been allocated for
+             * other purposes.
+             */
+            vpl011->evtchn = 0;
+        }
     }
     else
-        xfree(vpl011->backend.xen);
+        XFREE(vpl011->backend.xen);
 }
 
 /*
-- 
2.25.1




 


Rackspace

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