aboutsummaryrefslogtreecommitdiff
path: root/target/s390x
diff options
context:
space:
mode:
Diffstat (limited to 'target/s390x')
-rw-r--r--target/s390x/kvm.c35
1 files changed, 33 insertions, 2 deletions
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);