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

[PATCH] xen/arm: Fix memory leak in xenmem_add_to_physmap_one


  • To: <xen-devel@xxxxxxxxxxxxxxxxxxxx>
  • From: Michal Orzel <michal.orzel@xxxxxxx>
  • Date: Thu, 5 Feb 2026 13:58:20 +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 (0)
  • Arc-message-signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=microsoft.com; s=arcselector10001; 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=/9c1MjqVRjC0TadqvV4eh4kKo/EmKHGJVFivLDSc5iE=; b=t3B+n3C8kD6qexE971Fx3lNxp6U2VD/tRPCSN5usozl+ENeLT5Fnbjwp0d+oGBKsq7KJ8fZsmDDYj6O0SgYvvw/BsIyHVFPOz7D33BWmvrDQINVjzgTsyarEclORgn5bb9JbrYCJmatzOSAdErD/eG2USQb0sPbKvF5jQxZL3iFCCPWmRn0P7felGgSe6xY46ZCAeRBEWIoc4yuqZ6D47QimYKmikDaRDnj449XNvom28WjubjQa4H+63LGQLZKj+CtZjekiJH7r3s3GbkeLot/CvgCf5nGYJBvzyGw9MV5/ge8rUoBeEhB1MeJr2fKDYm4MtrnkU2I63irrVqr+gQ==
  • Arc-seal: i=1; a=rsa-sha256; s=arcselector10001; d=microsoft.com; cv=none; b=ILIklL1+02hRLseKuFTdjs+W1m9hAkec5XtcH8WjehH3p3kEspdWnFS4iLdhqc2ASaLuss+FhMQ09C1h6KYtEPisiiMsjMozZsWFMG/sRNDFblCskUEzLphX/TnbdvfnloFzFEfUXUM/qVrzkctXru6sw/H17lheWDLfoyUB9tKeQs9L2ErFSIKkChNA2DGI7Bq8/XsphnyPgL3Z5l7C/qJ5zzp040TMyh/GW7ccJo71sEJ4r5u0lUNndvNfpNv+3AOMeOVumED5MrUAK//WHytRUAq1Y9WudN4/fmjXYMPEUXWfqh7cRD/bZChfzMXD1hRuJXQR9GD1meHn8Wkr0w==
  • Cc: Michal Orzel <michal.orzel@xxxxxxx>, Stefano Stabellini <sstabellini@xxxxxxxxxx>, Julien Grall <julien@xxxxxxx>, Bertrand Marquis <bertrand.marquis@xxxxxxx>, Volodymyr Babchuk <Volodymyr_Babchuk@xxxxxxxx>, Xenia Ragiadakou <Xenia.Ragiadakou@xxxxxxx>
  • Delivery-date: Thu, 05 Feb 2026 12:59:05 +0000
  • List-id: Xen developer discussion <xen-devel.lists.xenproject.org>

When a guest maps pages via XENMEM_add_to_physmap to a GFN that already
has an existing mapping, the old page at that GFN was not being removed,
causing a memory leak. This affects all mapping spaces including
XENMAPSPACE_shared_info, XENMAPSPACE_grant_table, and
XENMAPSPACE_gmfn_foreign. The memory would be reclaimed on domain
destruction.

Add logic to remove the previously mapped page before creating the new
mapping, matching the x86 implementation approach.

Additionally, skip removal if the same MFN is being remapped.

Signed-off-by: Michal Orzel <michal.orzel@xxxxxxx>
---
I'm not sure where to point the Fixes tag to.
---
 xen/arch/arm/mm.c | 32 +++++++++++++++++++++++++++++---
 1 file changed, 29 insertions(+), 3 deletions(-)

diff --git a/xen/arch/arm/mm.c b/xen/arch/arm/mm.c
index 6df8b616e464..b9f1a493dcd7 100644
--- a/xen/arch/arm/mm.c
+++ b/xen/arch/arm/mm.c
@@ -166,10 +166,11 @@ int xenmem_add_to_physmap_one(
     unsigned long idx,
     gfn_t gfn)
 {
-    mfn_t mfn = INVALID_MFN;
+    mfn_t mfn = INVALID_MFN, mfn_old;
     int rc;
     p2m_type_t t;
     struct page_info *page = NULL;
+    struct p2m_domain *p2m = p2m_get_hostp2m(d);
 
     switch ( space )
     {
@@ -244,6 +245,33 @@ int xenmem_add_to_physmap_one(
         return -ENOSYS;
     }
 
+    /*
+     * Remove previously mapped page if it was present, to avoid leaking
+     * memory.
+     */
+    mfn_old = gfn_to_mfn(d, gfn);
+
+    if ( mfn_valid(mfn_old) )
+    {
+        if ( is_special_page(mfn_to_page(mfn_old)) )
+        {
+            /* Just unmap, don't free */
+            p2m_write_lock(p2m);
+            rc = p2m_set_entry(p2m, gfn, 1, INVALID_MFN,
+                               p2m_invalid, p2m->default_access);
+            p2m_write_unlock(p2m);
+            if ( rc )
+                return rc;
+        }
+        else if ( !mfn_eq(mfn, mfn_old) )
+        {
+            /* Normal domain memory is freed, to avoid leaking memory */
+            rc = guest_remove_page(d, gfn_x(gfn));
+            if ( rc )
+                return rc;
+        }
+    }
+
     /*
      * Map at new location. Here we need to map xenheap RAM page differently
      * because we need to store the valid GFN and make sure that nothing was
@@ -255,8 +283,6 @@ int xenmem_add_to_physmap_one(
         rc = guest_physmap_add_entry(d, gfn, mfn, 0, t);
     else
     {
-        struct p2m_domain *p2m = p2m_get_hostp2m(d);
-
         p2m_write_lock(p2m);
         if ( gfn_eq(page_get_xenheap_gfn(mfn_to_page(mfn)), INVALID_GFN) )
         {
-- 
2.43.0




 


Rackspace

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