diff options
Diffstat (limited to 'hw')
-rw-r--r-- | hw/ppc/spapr.c | 17 | ||||
-rw-r--r-- | hw/ppc/spapr_caps.c | 21 |
2 files changed, 28 insertions, 10 deletions
diff --git a/hw/ppc/spapr.c b/hw/ppc/spapr.c index 70b150b..0d032a1 100644 --- a/hw/ppc/spapr.c +++ b/hw/ppc/spapr.c @@ -3192,11 +3192,13 @@ static void spapr_memory_pre_plug(HotplugHandler *hotplug_dev, DeviceState *dev, Error **errp) { const sPAPRMachineClass *smc = SPAPR_MACHINE_GET_CLASS(hotplug_dev); + sPAPRMachineState *spapr = SPAPR_MACHINE(hotplug_dev); PCDIMMDevice *dimm = PC_DIMM(dev); PCDIMMDeviceClass *ddc = PC_DIMM_GET_CLASS(dimm); MemoryRegion *mr; uint64_t size; - char *mem_dev; + Object *memdev; + hwaddr pagesize; if (!smc->dr_lmb_enabled) { error_setg(errp, "Memory hotplug not supported for this machine"); @@ -3215,15 +3217,10 @@ static void spapr_memory_pre_plug(HotplugHandler *hotplug_dev, DeviceState *dev, return; } - mem_dev = object_property_get_str(OBJECT(dimm), PC_DIMM_MEMDEV_PROP, NULL); - if (mem_dev && !kvmppc_is_mem_backend_page_size_ok(mem_dev)) { - error_setg(errp, "Memory backend has bad page size. " - "Use 'memory-backend-file' with correct mem-path."); - goto out; - } - -out: - g_free(mem_dev); + memdev = object_property_get_link(OBJECT(dimm), PC_DIMM_MEMDEV_PROP, + &error_abort); + pagesize = host_memory_backend_pagesize(MEMORY_BACKEND(memdev)); + spapr_check_pagesize(spapr, pagesize, errp); } struct sPAPRDIMMState { diff --git a/hw/ppc/spapr_caps.c b/hw/ppc/spapr_caps.c index 6cdc0c9..722b213 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] = { |