aboutsummaryrefslogtreecommitdiff
path: root/hw/ppc/spapr_caps.c
diff options
context:
space:
mode:
authorDavid Gibson <david@gibson.dropbear.id.au>2018-04-18 14:21:45 +1000
committerDavid Gibson <david@gibson.dropbear.id.au>2018-06-22 14:19:07 +1000
commit123eec655287e43e0e86154e8093a394aefa3958 (patch)
tree357c075e950822ba5744bf746d52337ac7079172 /hw/ppc/spapr_caps.c
parent2309832afdaf8d6451ebc2e81bace8eb8ea41293 (diff)
spapr: Use maximum page size capability to simplify memory backend checking
The way we used to handle KVM allowable guest pagesizes for PAPR guests required some convoluted checking of memory attached to the guest. The allowable pagesizes advertised to the guest cpus depended on the memory which was attached at boot, but then we needed to ensure that any memory later hotplugged didn't change which pagesizes were allowed. Now that we have an explicit machine option to control the allowable maximum pagesize we can simplify this. We just check all memory backends against that declared pagesize. We check base and cold-plugged memory at reset time, and hotplugged memory at pre_plug() time. Signed-off-by: David Gibson <david@gibson.dropbear.id.au> Reviewed-by: Cédric Le Goater <clg@kaod.org> Reviewed-by: Greg Kurz <groug@kaod.org>
Diffstat (limited to 'hw/ppc/spapr_caps.c')
-rw-r--r--hw/ppc/spapr_caps.c21
1 files changed, 21 insertions, 0 deletions
diff --git a/hw/ppc/spapr_caps.c b/hw/ppc/spapr_caps.c
index 6cdc0c94e7..722b213d9a 100644
--- a/hw/ppc/spapr_caps.c
+++ b/hw/ppc/spapr_caps.c
@@ -26,6 +26,7 @@
#include "qapi/error.h"
#include "qapi/visitor.h"
#include "sysemu/hw_accel.h"
+#include "exec/ram_addr.h"
#include "target/ppc/cpu.h"
#include "target/ppc/mmu-hash64.h"
#include "cpu-models.h"
@@ -304,14 +305,34 @@ static void cap_safe_indirect_branch_apply(sPAPRMachineState *spapr,
#define VALUE_DESC_TRISTATE " (broken, workaround, fixed)"
+void spapr_check_pagesize(sPAPRMachineState *spapr, hwaddr pagesize,
+ Error **errp)
+{
+ hwaddr maxpagesize = (1ULL << spapr->eff.caps[SPAPR_CAP_HPT_MAXPAGESIZE]);
+
+ if (!kvmppc_hpt_needs_host_contiguous_pages()) {
+ return;
+ }
+
+ if (maxpagesize > pagesize) {
+ error_setg(errp,
+ "Can't support %"HWADDR_PRIu" kiB guest pages with %"
+ HWADDR_PRIu" kiB host pages with this KVM implementation",
+ maxpagesize >> 10, pagesize >> 10);
+ }
+}
+
static void cap_hpt_maxpagesize_apply(sPAPRMachineState *spapr,
uint8_t val, Error **errp)
{
if (val < 12) {
error_setg(errp, "Require at least 4kiB hpt-max-page-size");
+ return;
} else if (val < 16) {
warn_report("Many guests require at least 64kiB hpt-max-page-size");
}
+
+ spapr_check_pagesize(spapr, qemu_getrampagesize(), errp);
}
sPAPRCapabilityInfo capability_table[SPAPR_CAP_NUM] = {