Browse Source

KVM: s390: Make huge pages unavailable in ucontrol VMs

We currently do not notify all gmaps when using gmap_pmdp_xchg(), due
to locking constraints. This makes ucontrol VMs, which is the only VM
type that creates multiple gmaps, incompatible with huge pages. Also
we would need to hold the guest_table_lock of all gmaps that have this
vmaddr maped to synchronize access to the pmd.

ucontrol VMs are rather exotic and creating a new locking concept is
no easy task. Hence we return EINVAL when trying to active
KVM_CAP_S390_HPAGE_1M and report it as being not available when
checking for it.

Fixes: a4499382 ("KVM: s390: Add huge page enablement control")
Signed-off-by: Janosch Frank <frankja@linux.ibm.com>
Reviewed-by: David Hildenbrand <david@redhat.com>
Reviewed-by: Claudio Imbrenda <imbrenda@linux.ibm.com>
Message-Id: <20180801112508.138159-1-frankja@linux.ibm.com>
Signed-off-by: Janosch Frank <frankja@linux.ibm.com>
Janosch Frank 7 years ago
parent
commit
40ebdb8e59
2 changed files with 4 additions and 3 deletions
  1. 2 1
      Documentation/virtual/kvm/api.txt
  2. 2 2
      arch/s390/kvm/kvm-s390.c

+ 2 - 1
Documentation/virtual/kvm/api.txt

@@ -4510,7 +4510,8 @@ Do not enable KVM_FEATURE_PV_UNHALT if you disable HLT exits.
 Architectures: s390
 Architectures: s390
 Parameters: none
 Parameters: none
 Returns: 0 on success, -EINVAL if hpage module parameter was not set
 Returns: 0 on success, -EINVAL if hpage module parameter was not set
-	 or cmma is enabled
+	 or cmma is enabled, or the VM has the KVM_VM_S390_UCONTROL
+	 flag set
 
 
 With this capability the KVM support for memory backing with 1m pages
 With this capability the KVM support for memory backing with 1m pages
 through hugetlbfs can be enabled for a VM. After the capability is
 through hugetlbfs can be enabled for a VM. After the capability is

+ 2 - 2
arch/s390/kvm/kvm-s390.c

@@ -481,7 +481,7 @@ int kvm_vm_ioctl_check_extension(struct kvm *kvm, long ext)
 		break;
 		break;
 	case KVM_CAP_S390_HPAGE_1M:
 	case KVM_CAP_S390_HPAGE_1M:
 		r = 0;
 		r = 0;
-		if (hpage)
+		if (hpage && !kvm_is_ucontrol(kvm))
 			r = 1;
 			r = 1;
 		break;
 		break;
 	case KVM_CAP_S390_MEM_OP:
 	case KVM_CAP_S390_MEM_OP:
@@ -691,7 +691,7 @@ static int kvm_vm_ioctl_enable_cap(struct kvm *kvm, struct kvm_enable_cap *cap)
 		mutex_lock(&kvm->lock);
 		mutex_lock(&kvm->lock);
 		if (kvm->created_vcpus)
 		if (kvm->created_vcpus)
 			r = -EBUSY;
 			r = -EBUSY;
-		else if (!hpage || kvm->arch.use_cmma)
+		else if (!hpage || kvm->arch.use_cmma || kvm_is_ucontrol(kvm))
 			r = -EINVAL;
 			r = -EINVAL;
 		else {
 		else {
 			r = 0;
 			r = 0;