diff --git a/target/s390x/kvm.c b/target/s390x/kvm.c index af83955e5f..348e8cc546 100644 --- a/target/s390x/kvm.c +++ b/target/s390x/kvm.c @@ -34,6 +34,8 @@ #include "qapi/error.h" #include "qemu/error-report.h" #include "qemu/timer.h" +#include "qemu/units.h" +#include "qemu/mmap-alloc.h" #include "sysemu/sysemu.h" #include "sysemu/hw_accel.h" #include "hw/hw.h" @@ -139,6 +141,7 @@ static int cap_mem_op; static int cap_s390_irq; static int cap_ri; static int cap_gs; +static int cap_hpage_1m; static int active_cmma; @@ -220,9 +223,9 @@ static void kvm_s390_enable_cmma(void) .attr = KVM_S390_VM_MEM_ENABLE_CMMA, }; - if (mem_path) { + if (cap_hpage_1m) { warn_report("CMM will not be enabled because it is not " - "compatible with hugetlbfs."); + "compatible with huge memory backings."); return; } rc = kvm_vm_ioctl(kvm_state, KVM_SET_DEVICE_ATTR, &attr); @@ -281,10 +284,38 @@ void kvm_s390_crypto_reset(void) } } +static int kvm_s390_configure_mempath_backing(KVMState *s) +{ + size_t path_psize = qemu_mempath_getpagesize(mem_path); + + if (path_psize == 4 * KiB) { + return 0; + } + + if (path_psize != 1 * MiB) { + error_report("Memory backing with 2G pages was specified, " + "but KVM does not support this memory backing"); + return -EINVAL; + } + + if (kvm_vm_enable_cap(s, KVM_CAP_S390_HPAGE_1M, 0)) { + error_report("Memory backing with 1M pages was specified, " + "but KVM does not support this memory backing"); + return -EINVAL; + } + + cap_hpage_1m = 1; + return 0; +} + int kvm_arch_init(MachineState *ms, KVMState *s) { MachineClass *mc = MACHINE_GET_CLASS(ms); + if (mem_path && kvm_s390_configure_mempath_backing(s)) { + return -EINVAL; + } + mc->default_cpu_type = S390_CPU_TYPE_NAME("host"); cap_sync_regs = kvm_check_extension(s, KVM_CAP_SYNC_REGS); cap_async_pf = kvm_check_extension(s, KVM_CAP_ASYNC_PF);