Skip to content

Commit a449938

Browse files
committed
KVM: s390: Add huge page enablement control
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>
1 parent a9e00d8 commit a449938

File tree

3 files changed

+57
-2
lines changed

3 files changed

+57
-2
lines changed

Documentation/virtual/kvm/api.txt

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4391,6 +4391,22 @@ all such vmexits.
43914391

43924392
Do not enable KVM_FEATURE_PV_UNHALT if you disable HLT exits.
43934393

4394+
7.14 KVM_CAP_S390_HPAGE_1M
4395+
4396+
Architectures: s390
4397+
Parameters: none
4398+
Returns: 0 on success, -EINVAL if hpage module parameter was not set
4399+
or cmma is enabled
4400+
4401+
With this capability the KVM support for memory backing with 1m pages
4402+
through hugetlbfs can be enabled for a VM. After the capability is
4403+
enabled, cmma can't be enabled anymore and pfmfi and the storage key
4404+
interpretation are disabled. If cmma has already been enabled or the
4405+
hpage module parameter is not set to 1, -EINVAL is returned.
4406+
4407+
While it is generally possible to create a huge page backed VM without
4408+
this capability, the VM will not be able to run.
4409+
43944410
8. Other capabilities.
43954411
----------------------
43964412

arch/s390/kvm/kvm-s390.c

Lines changed: 40 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -172,6 +172,10 @@ static int nested;
172172
module_param(nested, int, S_IRUGO);
173173
MODULE_PARM_DESC(nested, "Nested virtualization support");
174174

175+
/* allow 1m huge page guest backing, if !nested */
176+
static int hpage;
177+
module_param(hpage, int, 0444);
178+
MODULE_PARM_DESC(hpage, "1m huge page backing support");
175179

176180
/*
177181
* 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)
475479
case KVM_CAP_S390_AIS_MIGRATION:
476480
r = 1;
477481
break;
482+
case KVM_CAP_S390_HPAGE_1M:
483+
r = 0;
484+
if (hpage)
485+
r = 1;
486+
break;
478487
case KVM_CAP_S390_MEM_OP:
479488
r = MEM_OP_MAX_SIZE;
480489
break;
@@ -678,6 +687,27 @@ static int kvm_vm_ioctl_enable_cap(struct kvm *kvm, struct kvm_enable_cap *cap)
678687
VM_EVENT(kvm, 3, "ENABLE: CAP_S390_GS %s",
679688
r ? "(not available)" : "(success)");
680689
break;
690+
case KVM_CAP_S390_HPAGE_1M:
691+
mutex_lock(&kvm->lock);
692+
if (kvm->created_vcpus)
693+
r = -EBUSY;
694+
else if (!hpage || kvm->arch.use_cmma)
695+
r = -EINVAL;
696+
else {
697+
r = 0;
698+
kvm->mm->context.allow_gmap_hpage_1m = 1;
699+
/*
700+
* We might have to create fake 4k page
701+
* tables. To avoid that the hardware works on
702+
* stale PGSTEs, we emulate these instructions.
703+
*/
704+
kvm->arch.use_skf = 0;
705+
kvm->arch.use_pfmfi = 0;
706+
}
707+
mutex_unlock(&kvm->lock);
708+
VM_EVENT(kvm, 3, "ENABLE: CAP_S390_HPAGE %s",
709+
r ? "(not available)" : "(success)");
710+
break;
681711
case KVM_CAP_S390_USER_STSI:
682712
VM_EVENT(kvm, 3, "%s", "ENABLE: CAP_S390_USER_STSI");
683713
kvm->arch.user_stsi = 1;
@@ -725,10 +755,13 @@ static int kvm_s390_set_mem_control(struct kvm *kvm, struct kvm_device_attr *att
725755
if (!sclp.has_cmma)
726756
break;
727757

728-
ret = -EBUSY;
729758
VM_EVENT(kvm, 3, "%s", "ENABLE: CMMA support");
730759
mutex_lock(&kvm->lock);
731-
if (!kvm->created_vcpus) {
760+
if (kvm->created_vcpus)
761+
ret = -EBUSY;
762+
else if (kvm->mm->context.allow_gmap_hpage_1m)
763+
ret = -EINVAL;
764+
else {
732765
kvm->arch.use_cmma = 1;
733766
/* Not compatible with cmma. */
734767
kvm->arch.use_pfmfi = 0;
@@ -4102,6 +4135,11 @@ static int __init kvm_s390_init(void)
41024135
return -ENODEV;
41034136
}
41044137

4138+
if (nested && hpage) {
4139+
pr_info("nested (vSIE) and hpage (huge page backing) can currently not be activated concurrently");
4140+
return -EINVAL;
4141+
}
4142+
41054143
for (i = 0; i < 16; i++)
41064144
kvm_s390_fac_base[i] |=
41074145
S390_lowcore.stfle_fac_list[i] & nonhyp_mask(i);

include/uapi/linux/kvm.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -949,6 +949,7 @@ struct kvm_ppc_resize_hpt {
949949
#define KVM_CAP_GET_MSR_FEATURES 153
950950
#define KVM_CAP_HYPERV_EVENTFD 154
951951
#define KVM_CAP_HYPERV_TLBFLUSH 155
952+
#define KVM_CAP_S390_HPAGE_1M 156
952953

953954
#ifdef KVM_CAP_IRQ_ROUTING
954955

0 commit comments

Comments
 (0)