drivers/xen/balloon.c | 23 +++++++++++++++-------- 1 file changed, 15 insertions(+), 8 deletions(-)
The handling of extra memory regions done in balloon_add_regions() is not
correct for PV guests, since the initial target is set to reflect the real
memory the system has, not what's described on the memory map, which can be
higher if memory != maxmem.
Introduce separate logic for PV vs HVM in balloon_add_regions() and handle
the extra region correctly by adding them to the total amount of pages,
instead of subtracting from the current and target pages amounts.
Fixes: 87af633689ce ("x86/xen: fix balloon target initialization for PVH dom0")
Signed-off-by: Roger Pau Monné <roger@xenproject.org>
---
Cc: Yannick Martin <yannick.martin@okazoo.eu>
Cc: "Thorsten Leemhuis" <regressions@leemhuis.info>
---
drivers/xen/balloon.c | 23 +++++++++++++++--------
1 file changed, 15 insertions(+), 8 deletions(-)
diff --git a/drivers/xen/balloon.c b/drivers/xen/balloon.c
index e7f1d4ca6d75..c20a1ff8292d 100644
--- a/drivers/xen/balloon.c
+++ b/drivers/xen/balloon.c
@@ -703,19 +703,26 @@ static int __init balloon_add_regions(void)
balloon_append(pfn_to_page(pfn));
/*
- * Extra regions are accounted for in the physmap, but need
- * decreasing from current_pages and target_pages to balloon
- * down the initial allocation, because they are already
- * accounted for in total_pages.
+ * For HVM domains: extra regions are accounted for in the
+ * physmap, but need decreasing from current_pages and
+ * target_pages to balloon down the initial allocation, because
+ * they are already accounted for in total_pages.
+ *
+ * For PV domains: extra regions are not accounted for in the
+ * initial memory target, and hence need adding to the stats as
+ * additional unpopulated regions.
*/
pages = extra_pfn_end - start_pfn;
- if (pages >= balloon_stats.current_pages ||
- pages >= balloon_stats.target_pages) {
+ if (xen_pv_domain()) {
+ balloon_stats.total_pages += pages;
+ } else if (pages >= balloon_stats.current_pages ||
+ pages >= balloon_stats.target_pages) {
WARN(1, "Extra pages underflow current target");
return -ERANGE;
+ } else {
+ balloon_stats.current_pages -= pages;
+ balloon_stats.target_pages -= pages;
}
- balloon_stats.current_pages -= pages;
- balloon_stats.target_pages -= pages;
}
return 0;
--
2.53.0
Hi Roger,
thanks for picking this up, and Juergen, thanks for the quick review. Two
things I believe are still worth addressing; the Fixes: tag can of course
also be fixed up on application.
I think the Fixes: tag should point to 0949c646d646 ("Partial revert
\"x86/xen: fix balloon target initialization for PVH dom0\""). Commit
87af633689ce changed the initial-page calculation and the extra-region
subtraction together, so those two operations were coherent: the PV initial
count then came from get_num_physpages(), which includes the extra regions.
0949c646d646 restored the PV start_info->nr_pages calculation, which
excludes the extra regions, but retained the subtraction. Its 6.12.y
backport is also the reporter's identified regression, first seen in
6.12.75. Applying this patch in a tree that has 87af633689ce but not
0949c646d646 (for example a 6.17-based distro tree) would double-account
the extra region. This likely also wants Cc: stable@vger.kernel.org, since
both 6.12.y and 6.18.y carry the 0949c646d646 regression.
Separately, and not something this patch introduces: PVH dom0 has the same
shape of problem on mainline since b13cd24c15d7. A successful
XENMEM_current_reservation supplies current_pages for both PV and PVH dom0,
and that count excludes the unpopulated xen_extra_mem, so the
xen_pv_domain()-only branch leaves PVH dom0 subtracting those pages again
(-ERANGE, or a silently wrong target, when CONFIG_XEN_UNPOPULATED_ALLOC=n
leaves the regions for the balloon driver). I am happy to pursue that as
its own thread once this one lands.
Would it be safer to pass balloon_add_regions() an explicit indication of
whether the chosen initial-page count includes the extra physmap regions?
That would cover PV, PVH dom0, and the XENMEM_current_reservation fallback
without deriving the accounting rule solely from the domain type. On
hypercall failure PVH dom0 falls back to get_num_physpages(), which
includes the extra regions, so keying the accounting on the source of the
count keeps the fallback correct as well.
Thanks,
Matthias
On Wed, Aug 05, 2026 at 12:46:07PM +0800, Matthias Goergens wrote:
> Hi Roger,
>
> thanks for picking this up, and Juergen, thanks for the quick review. Two
> things I believe are still worth addressing; the Fixes: tag can of course
> also be fixed up on application.
>
> I think the Fixes: tag should point to 0949c646d646 ("Partial revert
> \"x86/xen: fix balloon target initialization for PVH dom0\""). Commit
> 87af633689ce changed the initial-page calculation and the extra-region
> subtraction together, so those two operations were coherent: the PV initial
> count then came from get_num_physpages(), which includes the extra regions.
> 0949c646d646 restored the PV start_info->nr_pages calculation, which
> excludes the extra regions, but retained the subtraction.
I've got the same doubts about which commit to reference in the Fixes
tag. Here is my reasoning for picking the original bogus commit, and
not the subsequent attempt at fixing it:
Even if 87af633689ce was coherent in the usage of initial pages vs
extra regions, it was still wrong, and that's why it was (partially)
reverted. I assume that anyone who picks the change in this patch
will also have picked 0949c646d646, otherwise they have a problem with
how they do backports.
> Its 6.12.y
> backport is also the reporter's identified regression, first seen in
> 6.12.75. Applying this patch in a tree that has 87af633689ce but not
> 0949c646d646 (for example a 6.17-based distro tree) would double-account
> the extra region.
Why would someone apply this fix but not the preceding one? It makes
no sense, you either pick backports consistently, or need to be very
careful at knowing what to pick (and assume that sometimes stuff will
break).
> This likely also wants Cc: stable@vger.kernel.org, since
> both 6.12.y and 6.18.y carry the 0949c646d646 regression.
>
> Separately, and not something this patch introduces: PVH dom0 has the same
> shape of problem on mainline since b13cd24c15d7. A successful
> XENMEM_current_reservation supplies current_pages for both PV and PVH dom0,
> and that count excludes the unpopulated xen_extra_mem, so the
> xen_pv_domain()-only branch leaves PVH dom0 subtracting those pages again
> (-ERANGE, or a silently wrong target, when CONFIG_XEN_UNPOPULATED_ALLOC=n
> leaves the regions for the balloon driver). I am happy to pursue that as
> its own thread once this one lands.
Hm, I see. Running a PVH dom0 without CONFIG_XEN_UNPOPULATED_ALLOC
will be a very bad idea anyway, as the kernel would likely end up
triggering an OOM as all pages would be ballooned out to create
grant/foreign mappings.
> Would it be safer to pass balloon_add_regions() an explicit indication of
> whether the chosen initial-page count includes the extra physmap regions?
> That would cover PV, PVH dom0, and the XENMEM_current_reservation fallback
> without deriving the accounting rule solely from the domain type. On
> hypercall failure PVH dom0 falls back to get_num_physpages(), which
> includes the extra regions, so keying the accounting on the source of the
> count keeps the fallback correct as well.
Possibly, this has grown organically to accommodate for the
lack of proper interface to do memory balloon accounting.
I will send v2 attempting to take care of the PVH corner case and the
error fallback. It's IMO best if we can get all the related fixes
here in a single patch to backport.
Thanks, Roger.
On 30.07.26 16:35, Roger Pau Monne wrote:
> The handling of extra memory regions done in balloon_add_regions() is not
> correct for PV guests, since the initial target is set to reflect the real
> memory the system has, not what's described on the memory map, which can be
> higher if memory != maxmem.
>
> Introduce separate logic for PV vs HVM in balloon_add_regions() and handle
> the extra region correctly by adding them to the total amount of pages,
> instead of subtracting from the current and target pages amounts.
>
> Fixes: 87af633689ce ("x86/xen: fix balloon target initialization for PVH dom0")
> Signed-off-by: Roger Pau Monné <roger@xenproject.org>
Reviewed-by: Juergen Gross <jgross@suse.com>
Juergen
© 2016 - 2026 Red Hat, Inc.