aboutsummaryrefslogtreecommitdiffstats
path: root/arch/s390
diff options
context:
space:
mode:
authorDominik Dingel <dingel@linux.vnet.ibm.com>2014-10-31 09:10:41 -0400
committerChristian Borntraeger <borntraeger@de.ibm.com>2015-01-23 07:25:30 -0500
commit8c0a7ce60676caa89c204a1a3b748e065f3d7182 (patch)
tree8f3b3f85b3c99edb88933dd27c210916752aa75e /arch/s390
parentdafd032a15f8f165a7d10e00217d3b74f70a7b0f (diff)
KVM: s390: Allow userspace to limit guest memory size
With commit c6c956b80bdf ("KVM: s390/mm: support gmap page tables with less than 5 levels") we are able to define a limit for the guest memory size. As we round up the guest size in respect to the levels of page tables we get to guest limits of: 2048 MB, 4096 GB, 8192 TB and 16384 PB. We currently limit the guest size to 16 TB, which means we end up creating a page table structure supporting guest sizes up to 8192 TB. This patch introduces an interface that allows userspace to tune this limit. This may bring performance improvements for small guests. Signed-off-by: Dominik Dingel <dingel@linux.vnet.ibm.com> Acked-by: Cornelia Huck <cornelia.huck@de.ibm.com> Signed-off-by: Christian Borntraeger <borntraeger@de.ibm.com>
Diffstat (limited to 'arch/s390')
-rw-r--r--arch/s390/include/uapi/asm/kvm.h1
-rw-r--r--arch/s390/kvm/kvm-s390.c65
2 files changed, 63 insertions, 3 deletions
diff --git a/arch/s390/include/uapi/asm/kvm.h b/arch/s390/include/uapi/asm/kvm.h
index 48eda3ab4944..9c01159cf667 100644
--- a/arch/s390/include/uapi/asm/kvm.h
+++ b/arch/s390/include/uapi/asm/kvm.h
@@ -61,6 +61,7 @@ struct kvm_s390_io_adapter_req {
61/* kvm attributes for mem_ctrl */ 61/* kvm attributes for mem_ctrl */
62#define KVM_S390_VM_MEM_ENABLE_CMMA 0 62#define KVM_S390_VM_MEM_ENABLE_CMMA 0
63#define KVM_S390_VM_MEM_CLR_CMMA 1 63#define KVM_S390_VM_MEM_CLR_CMMA 1
64#define KVM_S390_VM_MEM_LIMIT_SIZE 2
64 65
65/* for KVM_GET_REGS and KVM_SET_REGS */ 66/* for KVM_GET_REGS and KVM_SET_REGS */
66struct kvm_regs { 67struct kvm_regs {
diff --git a/arch/s390/kvm/kvm-s390.c b/arch/s390/kvm/kvm-s390.c
index 529f7905b341..14cdf1c3b995 100644
--- a/arch/s390/kvm/kvm-s390.c
+++ b/arch/s390/kvm/kvm-s390.c
@@ -261,7 +261,24 @@ static int kvm_vm_ioctl_enable_cap(struct kvm *kvm, struct kvm_enable_cap *cap)
261 return r; 261 return r;
262} 262}
263 263
264static int kvm_s390_mem_control(struct kvm *kvm, struct kvm_device_attr *attr) 264static int kvm_s390_get_mem_control(struct kvm *kvm, struct kvm_device_attr *attr)
265{
266 int ret;
267
268 switch (attr->attr) {
269 case KVM_S390_VM_MEM_LIMIT_SIZE:
270 ret = 0;
271 if (put_user(kvm->arch.gmap->asce_end, (u64 __user *)attr->addr))
272 ret = -EFAULT;
273 break;
274 default:
275 ret = -ENXIO;
276 break;
277 }
278 return ret;
279}
280
281static int kvm_s390_set_mem_control(struct kvm *kvm, struct kvm_device_attr *attr)
265{ 282{
266 int ret; 283 int ret;
267 unsigned int idx; 284 unsigned int idx;
@@ -283,6 +300,36 @@ static int kvm_s390_mem_control(struct kvm *kvm, struct kvm_device_attr *attr)
283 mutex_unlock(&kvm->lock); 300 mutex_unlock(&kvm->lock);
284 ret = 0; 301 ret = 0;
285 break; 302 break;
303 case KVM_S390_VM_MEM_LIMIT_SIZE: {
304 unsigned long new_limit;
305
306 if (kvm_is_ucontrol(kvm))
307 return -EINVAL;
308
309 if (get_user(new_limit, (u64 __user *)attr->addr))
310 return -EFAULT;
311
312 if (new_limit > kvm->arch.gmap->asce_end)
313 return -E2BIG;
314
315 ret = -EBUSY;
316 mutex_lock(&kvm->lock);
317 if (atomic_read(&kvm->online_vcpus) == 0) {
318 /* gmap_alloc will round the limit up */
319 struct gmap *new = gmap_alloc(current->mm, new_limit);
320
321 if (!new) {
322 ret = -ENOMEM;
323 } else {
324 gmap_free(kvm->arch.gmap);
325 new->private = kvm;
326 kvm->arch.gmap = new;
327 ret = 0;
328 }
329 }
330 mutex_unlock(&kvm->lock);
331 break;
332 }
286 default: 333 default:
287 ret = -ENXIO; 334 ret = -ENXIO;
288 break; 335 break;
@@ -296,7 +343,7 @@ static int kvm_s390_vm_set_attr(struct kvm *kvm, struct kvm_device_attr *attr)
296 343
297 switch (attr->group) { 344 switch (attr->group) {
298 case KVM_S390_VM_MEM_CTRL: 345 case KVM_S390_VM_MEM_CTRL:
299 ret = kvm_s390_mem_control(kvm, attr); 346 ret = kvm_s390_set_mem_control(kvm, attr);
300 break; 347 break;
301 default: 348 default:
302 ret = -ENXIO; 349 ret = -ENXIO;
@@ -308,7 +355,18 @@ static int kvm_s390_vm_set_attr(struct kvm *kvm, struct kvm_device_attr *attr)
308 355
309static int kvm_s390_vm_get_attr(struct kvm *kvm, struct kvm_device_attr *attr) 356static int kvm_s390_vm_get_attr(struct kvm *kvm, struct kvm_device_attr *attr)
310{ 357{
311 return -ENXIO; 358 int ret;
359
360 switch (attr->group) {
361 case KVM_S390_VM_MEM_CTRL:
362 ret = kvm_s390_get_mem_control(kvm, attr);
363 break;
364 default:
365 ret = -ENXIO;
366 break;
367 }
368
369 return ret;
312} 370}
313 371
314static int kvm_s390_vm_has_attr(struct kvm *kvm, struct kvm_device_attr *attr) 372static int kvm_s390_vm_has_attr(struct kvm *kvm, struct kvm_device_attr *attr)
@@ -320,6 +378,7 @@ static int kvm_s390_vm_has_attr(struct kvm *kvm, struct kvm_device_attr *attr)
320 switch (attr->attr) { 378 switch (attr->attr) {
321 case KVM_S390_VM_MEM_ENABLE_CMMA: 379 case KVM_S390_VM_MEM_ENABLE_CMMA:
322 case KVM_S390_VM_MEM_CLR_CMMA: 380 case KVM_S390_VM_MEM_CLR_CMMA:
381 case KVM_S390_VM_MEM_LIMIT_SIZE:
323 ret = 0; 382 ret = 0;
324 break; 383 break;
325 default: 384 default: