From: Roger Pau Monne <roger.pau@citrix.com>
To: xen-devel@lists.xenproject.org
Cc: Roger Pau Monne <roger.pau@citrix.com>,
Andrew Cooper <andrew.cooper3@citrix.com>,
Anthony PERARD <anthony.perard@vates.tech>,
Michal Orzel <michal.orzel@amd.com>,
Jan Beulich <jbeulich@suse.com>, Julien Grall <julien@xen.org>,
Stefano Stabellini <sstabellini@kernel.org>
Subject: [PATCH v2 2/3] xen/mm: do not assign pages to a domain until they are scrubbed
Date: Thu, 26 Mar 2026 09:51:44 +0100 [thread overview]
Message-ID: <20260326085145.61380-3-roger.pau@citrix.com> (raw)
In-Reply-To: <20260326085145.61380-1-roger.pau@citrix.com>
Assigning pages to a domain make them the possible target of hypercalls
like XENMEM_decrease_reservation ahead of such pages being scrubbed in
populate_physmap() when the guest is running in PV mode. This might allow
pages to be freed ahead of being scrubbed for example, as a stubdomain
already running could target them by guessing their MFNs. It's also
possible other action could set the page type ahead of scrubbing, which
would be problematic.
Prevent the pages pending scrub from being assigned to the domain, and only
do the assign once the scrubbing has finished. This has the disadvantage
that the allocated pages will be removed from the free pool, but not yet
accounted towards the domain consumed page quota. However there can only
be one stashed page in that state, and it's maximum size is bounded by the
memop-max-order option. This is not too different from the current logic,
where assigning pages to a domain (and thus checking whether such domain
doesn't overflow it's quota) is also done after the memory has been
allocated and removed from the pool of free pages.
Fixes: 83a784a15b47 ("xen/mm: allow deferred scrub of physmap populate allocated pages")
Reported-by: Jan Beulich <jbeulich@suse.com>
Signed-off-by: Roger Pau Monné <roger.pau@citrix.com>
---
xen/common/memory.c | 6 ++++++
xen/common/page_alloc.c | 9 ++++++++-
xen/include/xen/mm.h | 7 ++++++-
3 files changed, 20 insertions(+), 2 deletions(-)
diff --git a/xen/common/memory.c b/xen/common/memory.c
index f0ff1311881c..1ad4b51c5b02 100644
--- a/xen/common/memory.c
+++ b/xen/common/memory.c
@@ -388,6 +388,12 @@ static void populate_physmap(struct memop_args *a)
goto out;
}
}
+
+ if ( assign_page(page, a->extent_order, d, memflags) )
+ {
+ free_domheap_pages(page, a->extent_order);
+ goto out;
+ }
}
if ( unlikely(a->memflags & MEMF_no_tlbflush) )
diff --git a/xen/common/page_alloc.c b/xen/common/page_alloc.c
index 1316dfbd15ee..b1edef87124f 100644
--- a/xen/common/page_alloc.c
+++ b/xen/common/page_alloc.c
@@ -2713,7 +2713,14 @@ struct page_info *alloc_domheap_pages(
pg[i].count_info |= PGC_extra;
}
}
- if ( assign_page(pg, order, d, memflags) )
+ /*
+ * Don't add pages with the PGC_need_scrub bit set to the domain, the
+ * caller must clean the bit and then manually call assign_pages().
+ * Otherwise pages still subject to scrubbing would be reachable using
+ * get_page().
+ */
+ if ( !(memflags & MEMF_keep_scrub) &&
+ assign_page(pg, order, d, memflags) )
{
free_heap_pages(pg, order, memflags & MEMF_no_scrub);
return NULL;
diff --git a/xen/include/xen/mm.h b/xen/include/xen/mm.h
index 5e786c874a73..b80bec00c124 100644
--- a/xen/include/xen/mm.h
+++ b/xen/include/xen/mm.h
@@ -208,7 +208,12 @@ struct npfec {
#define MEMF_no_refcount (1U<<_MEMF_no_refcount)
#define _MEMF_populate_on_demand 1
#define MEMF_populate_on_demand (1U<<_MEMF_populate_on_demand)
-/* MEMF_keep_scrub is only valid when specified together with MEMF_no_scrub. */
+/*
+ * MEMF_keep_scrub is only valid when specified together with MEMF_no_scrub.
+ * Allocations with this flag never assign the pages to the domain, the caller
+ * must call assign_page() after the PGC_need_scrub bit is cleared if
+ * required.
+ */
#define _MEMF_keep_scrub 2
#define MEMF_keep_scrub (1U << _MEMF_keep_scrub)
#define _MEMF_no_dma 3
--
2.51.0
next prev parent reply other threads:[~2026-03-26 8:52 UTC|newest]
Thread overview: 8+ messages / expand[flat|nested] mbox.gz Atom feed top
2026-03-26 8:51 [PATCH v2 0/3] xen/mm: fix fallout from populate_physmap() deferred scrub change Roger Pau Monne
2026-03-26 8:51 ` [PATCH v2 1/3] xen/mm: don't unconditionally clear PGC_need_scrub in alloc_heap_pages() Roger Pau Monne
2026-03-26 8:51 ` Roger Pau Monne [this message]
2026-03-26 11:51 ` [PATCH v2 2/3] xen/mm: do not assign pages to a domain until they are scrubbed Jan Beulich
2026-03-26 8:51 ` [PATCH v2 3/3] xen/mm: improve freeing of partially scrubbed pages Roger Pau Monne
2026-03-26 11:50 ` Jan Beulich
2026-03-26 15:53 ` Roger Pau Monné
2026-03-26 16:05 ` Jan Beulich
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20260326085145.61380-3-roger.pau@citrix.com \
--to=roger.pau@citrix.com \
--cc=andrew.cooper3@citrix.com \
--cc=anthony.perard@vates.tech \
--cc=jbeulich@suse.com \
--cc=julien@xen.org \
--cc=michal.orzel@amd.com \
--cc=sstabellini@kernel.org \
--cc=xen-devel@lists.xenproject.org \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.