Code: static int __init balloon_init(void)
{
	if (!xen_domain())
		return -ENODEV;

	pr_info("Initialising balloon driver\n");

#ifdef CONFIG_XEN_PV
	balloon_stats.current_pages = xen_pv_domain()
		? min(xen_start_info->nr_pages - xen_released_pages, max_pfn)
		: get_num_physpages();
#else
	balloon_stats.current_pages = get_num_physpages();
#endif
	balloon_stats.target_pages  = balloon_stats.current_pages;
	balloon_stats.balloon_low   = 0;
	balloon_stats.balloon_high  = 0;
	balloon_stats.total_pages   = balloon_stats.current_pages;

 	balloon_stats.schedule_delay = 1;
 	balloon_stats.max_schedule_delay = 32;
 	balloon_stats.retry_count = 1;
	balloon_stats.max_retry_count = RETRY_UNLIMITED;
 
 #ifdef CONFIG_XEN_BALLOON_MEMORY_HOTPLUG
 	set_online_page_callback(&xen_online_page);
	register_memory_notifier(&xen_memory_nb);
	register_sysctl_table(xen_root);
#endif

#ifdef CONFIG_XEN_PV
	{
		int i;

		/*
		 * Initialize the balloon with pages from the extra memory
		 * regions (see arch/x86/xen/setup.c).
		 */
		for (i = 0; i < XEN_EXTRA_MEM_MAX_REGIONS; i++)
			if (xen_extra_mem[i].n_pfns)
				balloon_add_region(xen_extra_mem[i].start_pfn,
						   xen_extra_mem[i].n_pfns);
	}
#endif

	/* Init the xen-balloon driver. */
	xen_balloon_init();

	return 0;
}

Commit Message: xen: let alloc_xenballooned_pages() fail if not enough memory free

commit a1078e821b605813b63bf6bca414a85f804d5c66 upstream.

Instead of trying to allocate pages with GFP_USER in
add_ballooned_pages() check the available free memory via
si_mem_available(). GFP_USER is far less limiting memory exhaustion
than the test via si_mem_available().

This will avoid dom0 running out of memory due to excessive foreign
page mappings especially on ARM and on x86 in PVH mode, as those don't
have a pre-ballooned area which can be used for foreign mappings.

As the normal ballooning suffers from the same problem don't balloon
down more than si_mem_available() pages in one iteration. At the same
time limit the default maximum number of retries.

This is part of XSA-300.

Signed-off-by: Juergen Gross <jgross@suse.com>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
CWE ID: CWE-400
static int __init balloon_init(void)
{
	if (!xen_domain())
		return -ENODEV;

	pr_info("Initialising balloon driver\n");

#ifdef CONFIG_XEN_PV
	balloon_stats.current_pages = xen_pv_domain()
		? min(xen_start_info->nr_pages - xen_released_pages, max_pfn)
		: get_num_physpages();
#else
	balloon_stats.current_pages = get_num_physpages();
#endif
	balloon_stats.target_pages  = balloon_stats.current_pages;
	balloon_stats.balloon_low   = 0;
	balloon_stats.balloon_high  = 0;
	balloon_stats.total_pages   = balloon_stats.current_pages;

 	balloon_stats.schedule_delay = 1;
 	balloon_stats.max_schedule_delay = 32;
 	balloon_stats.retry_count = 1;
	balloon_stats.max_retry_count = 4;
 
 #ifdef CONFIG_XEN_BALLOON_MEMORY_HOTPLUG
 	set_online_page_callback(&xen_online_page);
	register_memory_notifier(&xen_memory_nb);
	register_sysctl_table(xen_root);
#endif

#ifdef CONFIG_XEN_PV
	{
		int i;

		/*
		 * Initialize the balloon with pages from the extra memory
		 * regions (see arch/x86/xen/setup.c).
		 */
		for (i = 0; i < XEN_EXTRA_MEM_MAX_REGIONS; i++)
			if (xen_extra_mem[i].n_pfns)
				balloon_add_region(xen_extra_mem[i].start_pfn,
						   xen_extra_mem[i].n_pfns);
	}
#endif

	/* Init the xen-balloon driver. */
	xen_balloon_init();

	return 0;
}
