xen: fix booting ballooned down hvm guest

Commit 96edd61dcf ("xen/balloon: don't
online new memory initially") introduced a regression when booting a
HVM domain with memory less than mem-max: instead of ballooning down
immediately the system would try to use the memory up to mem-max
resulting in Xen crashing the domain.

For HVM domains the current size will be reflected in Xenstore node
memory/static-max instead of memory/target.

Additionally we have to trigger the ballooning process at once.

Cc: <stable@vger.kernel.org> # 4.13
Fixes: 96edd61dcf ("xen/balloon: don't
       online new memory initially")

Reported-by: Simon Gaiser <hw42@ipsumj.de>
Suggested-by: Boris Ostrovsky <boris.ostrovsky@oracle.com>
Signed-off-by: Juergen Gross <jgross@suse.com>
Reviewed-by: Boris Ostrovsky <boris.ostrovsky@oracle.com>
Signed-off-by: Boris Ostrovsky <boris.ostrovsky@oracle.com>
This commit is contained in:
Juergen Gross 2017-10-26 11:50:56 +02:00 committed by Boris Ostrovsky
parent 298d275d4d
commit 5266b8e444

View File

@ -57,7 +57,7 @@ static int register_balloon(struct device *dev);
static void watch_target(struct xenbus_watch *watch, static void watch_target(struct xenbus_watch *watch,
const char *path, const char *token) const char *path, const char *token)
{ {
unsigned long long new_target; unsigned long long new_target, static_max;
int err; int err;
static bool watch_fired; static bool watch_fired;
static long target_diff; static long target_diff;
@ -72,13 +72,20 @@ static void watch_target(struct xenbus_watch *watch,
* pages. PAGE_SHIFT converts bytes to pages, hence PAGE_SHIFT - 10. * pages. PAGE_SHIFT converts bytes to pages, hence PAGE_SHIFT - 10.
*/ */
new_target >>= PAGE_SHIFT - 10; new_target >>= PAGE_SHIFT - 10;
if (watch_fired) {
balloon_set_new_target(new_target - target_diff); if (!watch_fired) {
return; watch_fired = true;
err = xenbus_scanf(XBT_NIL, "memory", "static-max", "%llu",
&static_max);
if (err != 1)
static_max = new_target;
else
static_max >>= PAGE_SHIFT - 10;
target_diff = xen_pv_domain() ? 0
: static_max - balloon_stats.target_pages;
} }
watch_fired = true; balloon_set_new_target(new_target - target_diff);
target_diff = new_target - balloon_stats.target_pages;
} }
static struct xenbus_watch target_watch = { static struct xenbus_watch target_watch = {
.node = "memory/target", .node = "memory/target",