]> git.proxmox.com Git - mirror_ubuntu-disco-kernel.git/commitdiff
KVM: s390: Add huge page enablement control
authorJanosch Frank <frankja@linux.ibm.com>
Fri, 13 Jul 2018 10:28:31 +0000 (11:28 +0100)
committerJanosch Frank <frankja@linux.ibm.com>
Mon, 30 Jul 2018 21:13:38 +0000 (23:13 +0200)
General KVM huge page support on s390 has to be enabled via the
kvm.hpage module parameter. Either nested or hpage can be enabled, as
we currently do not support vSIE for huge backed guests. Once the vSIE
support is added we will either drop the parameter or enable it as
default.

For a guest the feature has to be enabled through the new
KVM_CAP_S390_HPAGE_1M capability and the hpage module
parameter. Enabling it means that cmm can't be enabled for the vm and
disables pfmf and storage key interpretation.

This is due to the fact that in some cases, in upcoming patches, we
have to split huge pages in the guest mapping to be able to set more
granular memory protection on 4k pages. These split pages have fake
page tables that are not visible to the Linux memory management which
subsequently will not manage its PGSTEs, while the SIE will. Disabling
these features lets us manage PGSTE data in a consistent matter and
solve that problem.

Signed-off-by: Janosch Frank <frankja@linux.ibm.com>
Reviewed-by: David Hildenbrand <david@redhat.com>
Documentation/virtual/kvm/api.txt
arch/s390/kvm/kvm-s390.c
include/uapi/linux/kvm.h

index d10944e619d3d28c43bcca85bc3dd2761cee37f0..cb8db4f9d09794d6bc5cef908406fcc3ee76e213 100644 (file)
@@ -4391,6 +4391,22 @@ all such vmexits.
 
 Do not enable KVM_FEATURE_PV_UNHALT if you disable HLT exits.
 
+7.14 KVM_CAP_S390_HPAGE_1M
+
+Architectures: s390
+Parameters: none
+Returns: 0 on success, -EINVAL if hpage module parameter was not set
+        or cmma is enabled
+
+With this capability the KVM support for memory backing with 1m pages
+through hugetlbfs can be enabled for a VM. After the capability is
+enabled, cmma can't be enabled anymore and pfmfi and the storage key
+interpretation are disabled. If cmma has already been enabled or the
+hpage module parameter is not set to 1, -EINVAL is returned.
+
+While it is generally possible to create a huge page backed VM without
+this capability, the VM will not be able to run.
+
 8. Other capabilities.
 ----------------------
 
index 662f4d8046db2ff3bdeaa386daf0cd7c6b369235..f9d90337e64a6c0d26a102fea2329e74ff917bc6 100644 (file)
@@ -172,6 +172,10 @@ static int nested;
 module_param(nested, int, S_IRUGO);
 MODULE_PARM_DESC(nested, "Nested virtualization support");
 
+/* allow 1m huge page guest backing, if !nested */
+static int hpage;
+module_param(hpage, int, 0444);
+MODULE_PARM_DESC(hpage, "1m huge page backing support");
 
 /*
  * For now we handle at most 16 double words as this is what the s390 base
@@ -475,6 +479,11 @@ int kvm_vm_ioctl_check_extension(struct kvm *kvm, long ext)
        case KVM_CAP_S390_AIS_MIGRATION:
                r = 1;
                break;
+       case KVM_CAP_S390_HPAGE_1M:
+               r = 0;
+               if (hpage)
+                       r = 1;
+               break;
        case KVM_CAP_S390_MEM_OP:
                r = MEM_OP_MAX_SIZE;
                break;
@@ -678,6 +687,27 @@ static int kvm_vm_ioctl_enable_cap(struct kvm *kvm, struct kvm_enable_cap *cap)
                VM_EVENT(kvm, 3, "ENABLE: CAP_S390_GS %s",
                         r ? "(not available)" : "(success)");
                break;
+       case KVM_CAP_S390_HPAGE_1M:
+               mutex_lock(&kvm->lock);
+               if (kvm->created_vcpus)
+                       r = -EBUSY;
+               else if (!hpage || kvm->arch.use_cmma)
+                       r = -EINVAL;
+               else {
+                       r = 0;
+                       kvm->mm->context.allow_gmap_hpage_1m = 1;
+                       /*
+                        * We might have to create fake 4k page
+                        * tables. To avoid that the hardware works on
+                        * stale PGSTEs, we emulate these instructions.
+                        */
+                       kvm->arch.use_skf = 0;
+                       kvm->arch.use_pfmfi = 0;
+               }
+               mutex_unlock(&kvm->lock);
+               VM_EVENT(kvm, 3, "ENABLE: CAP_S390_HPAGE %s",
+                        r ? "(not available)" : "(success)");
+               break;
        case KVM_CAP_S390_USER_STSI:
                VM_EVENT(kvm, 3, "%s", "ENABLE: CAP_S390_USER_STSI");
                kvm->arch.user_stsi = 1;
@@ -725,10 +755,13 @@ static int kvm_s390_set_mem_control(struct kvm *kvm, struct kvm_device_attr *att
                if (!sclp.has_cmma)
                        break;
 
-               ret = -EBUSY;
                VM_EVENT(kvm, 3, "%s", "ENABLE: CMMA support");
                mutex_lock(&kvm->lock);
-               if (!kvm->created_vcpus) {
+               if (kvm->created_vcpus)
+                       ret = -EBUSY;
+               else if (kvm->mm->context.allow_gmap_hpage_1m)
+                       ret = -EINVAL;
+               else {
                        kvm->arch.use_cmma = 1;
                        /* Not compatible with cmma. */
                        kvm->arch.use_pfmfi = 0;
@@ -4102,6 +4135,11 @@ static int __init kvm_s390_init(void)
                return -ENODEV;
        }
 
+       if (nested && hpage) {
+               pr_info("nested (vSIE) and hpage (huge page backing) can currently not be activated concurrently");
+               return -EINVAL;
+       }
+
        for (i = 0; i < 16; i++)
                kvm_s390_fac_base[i] |=
                        S390_lowcore.stfle_fac_list[i] & nonhyp_mask(i);
index b6270a3b38e9f3fb410e8c80d8658b2c01a8ef96..b955b986b3413ac2fd2a7262b6bbee29006a65aa 100644 (file)
@@ -949,6 +949,7 @@ struct kvm_ppc_resize_hpt {
 #define KVM_CAP_GET_MSR_FEATURES 153
 #define KVM_CAP_HYPERV_EVENTFD 154
 #define KVM_CAP_HYPERV_TLBFLUSH 155
+#define KVM_CAP_S390_HPAGE_1M 156
 
 #ifdef KVM_CAP_IRQ_ROUTING