Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux
1
fork

Configure Feed

Select the types of activity you want to include in your feed.

Partial revert "x86/xen: fix balloon target initialization for PVH dom0"

This partially reverts commit 87af633689ce16ddb166c80f32b120e50b1295de so
the current memory target for PV guests is still fetched from
start_info->nr_pages, which matches exactly what the toolstack sets the
initial memory target to.

Using get_num_physpages() is possible on PV also, but needs adjusting to
take into account the ISA hole and the PFN at 0 not considered usable
memory despite being populated, and hence would need extra adjustments.
Instead of carrying those extra adjustments switch back to the previous
code. That leaves Linux with a difference in how current memory target is
obtained for HVM vs PV, but that's better than adding extra logic just for
PV.

However if switching to start_info->nr_pages for PV domains we need to
differentiate between released pages (freed back to the hypervisor) as
opposed to pages in the physmap which are not populated to start with.
Introduce a new xen_unpopulated_pages to account for papges that have
never been populated, and hence in the PV case don't need subtracting.

Fixes: 87af633689ce ("x86/xen: fix balloon target initialization for PVH dom0")
Reported-by: James Dingwall <james@dingwall.me.uk>
Signed-off-by: Roger Pau Monné <roger.pau@citrix.com>
Reviewed-by: Juergen Gross <jgross@suse.com>
Signed-off-by: Juergen Gross <jgross@suse.com>
Message-ID: <20260128110510.46425-2-roger.pau@citrix.com>

authored by

Roger Pau Monne and committed by
Juergen Gross
0949c646 763baca7

+21 -5
+1 -1
arch/x86/xen/enlighten.c
··· 470 470 * driver to know how much of the physmap is unpopulated and 471 471 * set an accurate initial memory target. 472 472 */ 473 - xen_released_pages += xen_extra_mem[i].n_pfns; 473 + xen_unpopulated_pages += xen_extra_mem[i].n_pfns; 474 474 /* Zero so region is not also added to the balloon driver. */ 475 475 xen_extra_mem[i].n_pfns = 0; 476 476 }
+15 -4
drivers/xen/balloon.c
··· 724 724 static int __init balloon_init(void) 725 725 { 726 726 struct task_struct *task; 727 + unsigned long current_pages; 727 728 int rc; 728 729 729 730 if (!xen_domain()) ··· 732 731 733 732 pr_info("Initialising balloon driver\n"); 734 733 735 - if (xen_released_pages >= get_num_physpages()) { 736 - WARN(1, "Released pages underflow current target"); 737 - return -ERANGE; 734 + if (xen_pv_domain()) { 735 + if (xen_released_pages >= xen_start_info->nr_pages) 736 + goto underflow; 737 + current_pages = min(xen_start_info->nr_pages - 738 + xen_released_pages, max_pfn); 739 + } else { 740 + if (xen_unpopulated_pages >= get_num_physpages()) 741 + goto underflow; 742 + current_pages = get_num_physpages() - xen_unpopulated_pages; 738 743 } 739 744 740 - balloon_stats.current_pages = get_num_physpages() - xen_released_pages; 745 + balloon_stats.current_pages = current_pages; 741 746 balloon_stats.target_pages = balloon_stats.current_pages; 742 747 balloon_stats.balloon_low = 0; 743 748 balloon_stats.balloon_high = 0; ··· 774 767 xen_balloon_init(); 775 768 776 769 return 0; 770 + 771 + underflow: 772 + WARN(1, "Released pages underflow current target"); 773 + return -ERANGE; 777 774 } 778 775 subsys_initcall(balloon_init); 779 776
+3
drivers/xen/unpopulated-alloc.c
··· 18 18 19 19 static struct resource *target_resource; 20 20 21 + /* Pages to subtract from the memory count when setting balloon target. */ 22 + unsigned long xen_unpopulated_pages __initdata; 23 + 21 24 /* 22 25 * If arch is not happy with system "iomem_resource" being used for 23 26 * the region allocation it can provide it's own view by creating specific
+2
include/xen/xen.h
··· 69 69 #endif 70 70 71 71 #ifdef CONFIG_XEN_UNPOPULATED_ALLOC 72 + extern unsigned long xen_unpopulated_pages; 72 73 int xen_alloc_unpopulated_pages(unsigned int nr_pages, struct page **pages); 73 74 void xen_free_unpopulated_pages(unsigned int nr_pages, struct page **pages); 74 75 #include <linux/ioport.h> 75 76 int arch_xen_unpopulated_init(struct resource **res); 76 77 #else 78 + #define xen_unpopulated_pages 0UL 77 79 #include <xen/balloon.h> 78 80 static inline int xen_alloc_unpopulated_pages(unsigned int nr_pages, 79 81 struct page **pages)