aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorPaolo Bonzini <pbonzini@redhat.com>2015-11-02 04:42:36 -0500
committerPaolo Bonzini <pbonzini@redhat.com>2015-11-02 04:42:36 -0500
commit4d5140c5799e676f5a8fb805105e8806f2db1902 (patch)
treeb09eab65be4a658df3d1ad8543d7f7eed7cfca23
parent8c85ac1c0a1b41299370857765bc0950666ed5d9 (diff)
parent46b708ea875f14f5496109df053624199f3aae87 (diff)
Merge tag 'kvm-s390-next-20151028' of git://git.kernel.org/pub/scm/linux/kernel/git/kvms390/linux into HEAD
KVM: s390: Bugfix and cleanups There is one important bug fix for a potential memory corruption and/or guest errors for guests with 63 or 64 vCPUs. This fix would qualify for 4.3 but is some days too late giving that we are about to release 4.3. Given that this patch is cc stable >= 3.15 anyway, we can handle it via 4.4. merge window. This pull request also contains two cleanups.
-rw-r--r--arch/s390/kvm/intercept.c42
-rw-r--r--arch/s390/kvm/kvm-s390.c12
2 files changed, 28 insertions, 26 deletions
diff --git a/arch/s390/kvm/intercept.c b/arch/s390/kvm/intercept.c
index 7365e8a46032..b4a5aa110cec 100644
--- a/arch/s390/kvm/intercept.c
+++ b/arch/s390/kvm/intercept.c
@@ -336,28 +336,28 @@ static int handle_partial_execution(struct kvm_vcpu *vcpu)
336 return -EOPNOTSUPP; 336 return -EOPNOTSUPP;
337} 337}
338 338
339static const intercept_handler_t intercept_funcs[] = {
340 [0x00 >> 2] = handle_noop,
341 [0x04 >> 2] = handle_instruction,
342 [0x08 >> 2] = handle_prog,
343 [0x10 >> 2] = handle_noop,
344 [0x14 >> 2] = handle_external_interrupt,
345 [0x18 >> 2] = handle_noop,
346 [0x1C >> 2] = kvm_s390_handle_wait,
347 [0x20 >> 2] = handle_validity,
348 [0x28 >> 2] = handle_stop,
349 [0x38 >> 2] = handle_partial_execution,
350};
351
352int kvm_handle_sie_intercept(struct kvm_vcpu *vcpu) 339int kvm_handle_sie_intercept(struct kvm_vcpu *vcpu)
353{ 340{
354 intercept_handler_t func; 341 switch (vcpu->arch.sie_block->icptcode) {
355 u8 code = vcpu->arch.sie_block->icptcode; 342 case 0x00:
356 343 case 0x10:
357 if (code & 3 || (code >> 2) >= ARRAY_SIZE(intercept_funcs)) 344 case 0x18:
345 return handle_noop(vcpu);
346 case 0x04:
347 return handle_instruction(vcpu);
348 case 0x08:
349 return handle_prog(vcpu);
350 case 0x14:
351 return handle_external_interrupt(vcpu);
352 case 0x1c:
353 return kvm_s390_handle_wait(vcpu);
354 case 0x20:
355 return handle_validity(vcpu);
356 case 0x28:
357 return handle_stop(vcpu);
358 case 0x38:
359 return handle_partial_execution(vcpu);
360 default:
358 return -EOPNOTSUPP; 361 return -EOPNOTSUPP;
359 func = intercept_funcs[code >> 2]; 362 }
360 if (func)
361 return func(vcpu);
362 return -EOPNOTSUPP;
363} 363}
diff --git a/arch/s390/kvm/kvm-s390.c b/arch/s390/kvm/kvm-s390.c
index 618c85411a51..07a6aa896c12 100644
--- a/arch/s390/kvm/kvm-s390.c
+++ b/arch/s390/kvm/kvm-s390.c
@@ -514,7 +514,7 @@ static int kvm_s390_set_tod_high(struct kvm *kvm, struct kvm_device_attr *attr)
514 514
515 if (gtod_high != 0) 515 if (gtod_high != 0)
516 return -EINVAL; 516 return -EINVAL;
517 VM_EVENT(kvm, 3, "SET: TOD extension: 0x%x\n", gtod_high); 517 VM_EVENT(kvm, 3, "SET: TOD extension: 0x%x", gtod_high);
518 518
519 return 0; 519 return 0;
520} 520}
@@ -527,7 +527,7 @@ static int kvm_s390_set_tod_low(struct kvm *kvm, struct kvm_device_attr *attr)
527 return -EFAULT; 527 return -EFAULT;
528 528
529 kvm_s390_set_tod_clock(kvm, gtod); 529 kvm_s390_set_tod_clock(kvm, gtod);
530 VM_EVENT(kvm, 3, "SET: TOD base: 0x%llx\n", gtod); 530 VM_EVENT(kvm, 3, "SET: TOD base: 0x%llx", gtod);
531 return 0; 531 return 0;
532} 532}
533 533
@@ -559,7 +559,7 @@ static int kvm_s390_get_tod_high(struct kvm *kvm, struct kvm_device_attr *attr)
559 if (copy_to_user((void __user *)attr->addr, &gtod_high, 559 if (copy_to_user((void __user *)attr->addr, &gtod_high,
560 sizeof(gtod_high))) 560 sizeof(gtod_high)))
561 return -EFAULT; 561 return -EFAULT;
562 VM_EVENT(kvm, 3, "QUERY: TOD extension: 0x%x\n", gtod_high); 562 VM_EVENT(kvm, 3, "QUERY: TOD extension: 0x%x", gtod_high);
563 563
564 return 0; 564 return 0;
565} 565}
@@ -571,7 +571,7 @@ static int kvm_s390_get_tod_low(struct kvm *kvm, struct kvm_device_attr *attr)
571 gtod = kvm_s390_get_tod_clock_fast(kvm); 571 gtod = kvm_s390_get_tod_clock_fast(kvm);
572 if (copy_to_user((void __user *)attr->addr, &gtod, sizeof(gtod))) 572 if (copy_to_user((void __user *)attr->addr, &gtod, sizeof(gtod)))
573 return -EFAULT; 573 return -EFAULT;
574 VM_EVENT(kvm, 3, "QUERY: TOD base: 0x%llx\n", gtod); 574 VM_EVENT(kvm, 3, "QUERY: TOD base: 0x%llx", gtod);
575 575
576 return 0; 576 return 0;
577} 577}
@@ -1098,7 +1098,9 @@ int kvm_arch_init_vm(struct kvm *kvm, unsigned long type)
1098 if (!kvm->arch.sca) 1098 if (!kvm->arch.sca)
1099 goto out_err; 1099 goto out_err;
1100 spin_lock(&kvm_lock); 1100 spin_lock(&kvm_lock);
1101 sca_offset = (sca_offset + 16) & 0x7f0; 1101 sca_offset += 16;
1102 if (sca_offset + sizeof(struct sca_block) > PAGE_SIZE)
1103 sca_offset = 0;
1102 kvm->arch.sca = (struct sca_block *) ((char *) kvm->arch.sca + sca_offset); 1104 kvm->arch.sca = (struct sca_block *) ((char *) kvm->arch.sca + sca_offset);
1103 spin_unlock(&kvm_lock); 1105 spin_unlock(&kvm_lock);
1104 1106