Blob Blame History Raw
From 35dcc0b1cf6cf7e031f5e4f9bfd3eab9e98044dc Mon Sep 17 00:00:00 2001
From: David Gibson <dgibson@redhat.com>
Date: Tue, 5 Dec 2017 04:18:21 +0100
Subject: [PATCH 15/21] BZ1513294: spapr: Include "pre-plugged" DIMMS in ram
 size calculation at reset

RH-Author: David Gibson <dgibson@redhat.com>
Message-id: <20171205041821.28985-1-dgibson@redhat.com>
Patchwork-id: 78132
O-Subject: [RHL-7.5 qemu-kvm-rhev PATCH] BZ1513294: spapr: Include "pre-plugged" DIMMS in ram size calculation at reset
Bugzilla: 1513294
RH-Acked-by: Thomas Huth <thuth@redhat.com>
RH-Acked-by: Laurent Vivier <lvivier@redhat.com>
RH-Acked-by: Igor Mammedov <imammedo@redhat.com>

From: David Gibson <david@gibson.dropbear.id.au>

At guest reset time, we allocate a hash page table (HPT) for the guest
based on the guest's RAM size.  If dynamic HPT resizing is not available we
use the maximum RAM size, if it is we use the current RAM size.

But the "current RAM size" calculation is incorrect - we just use the
"base" ram_size from the machine structure.  This doesn't include any
pluggable DIMMs that are already plugged at reset time.

This means that if you try to start a 'pseries' machine with a DIMM
specified on the command line that's much larger than the "base" RAM size,
then the guest will get a woefully inadequate HPT.  This can lead to a
guest freeze during boot as it runs out of HPT space during initial MMU
setup.

Signed-off-by: David Gibson <david@gibson.dropbear.id.au>
Reviewed-by: Greg Kurz <groug@kaod.org>
Tested-by: Greg Kurz <groug@kaod.org>
(cherry picked from commit 768a20f3a491ed4afce73ebb65347d55251c0ebd)

Slightly modified logic downstream because we don't have the
get_plugged_memory_size() helper.

Signed-off-by: David Gibson <dgibson@redhat.com>
Signed-off-by: Miroslav Rezanina <mrezanin@redhat.com>
---
 hw/ppc/spapr.c | 6 +++++-
 1 file changed, 5 insertions(+), 1 deletion(-)

diff --git a/hw/ppc/spapr.c b/hw/ppc/spapr.c
index e3dce84..af7a3bb 100644
--- a/hw/ppc/spapr.c
+++ b/hw/ppc/spapr.c
@@ -1369,7 +1369,11 @@ void spapr_setup_hpt_and_vrma(sPAPRMachineState *spapr)
             && !spapr_ovec_test(spapr->ov5_cas, OV5_HPT_RESIZE))) {
         hpt_shift = spapr_hpt_shift_for_ramsize(MACHINE(spapr)->maxram_size);
     } else {
-        hpt_shift = spapr_hpt_shift_for_ramsize(MACHINE(spapr)->ram_size);
+        uint64_t current_ram_size;
+
+        current_ram_size = MACHINE(spapr)->ram_size +
+            pc_existing_dimms_capacity(&error_fatal);
+        hpt_shift = spapr_hpt_shift_for_ramsize(current_ram_size);
     }
     spapr_reallocate_hpt(spapr, hpt_shift, &error_fatal);
 
-- 
1.8.3.1