diff options
| -rw-r--r-- | arch/s390/kvm/interrupt.c | 7 | ||||
| -rw-r--r-- | arch/s390/kvm/kvm-s390.c | 6 | ||||
| -rw-r--r-- | arch/s390/kvm/priv.c | 2 | ||||
| -rw-r--r-- | arch/s390/kvm/sigp.c | 8 | ||||
| -rw-r--r-- | include/linux/kvm_host.h | 11 |
5 files changed, 24 insertions, 10 deletions
diff --git a/arch/s390/kvm/interrupt.c b/arch/s390/kvm/interrupt.c index 373e32346d68..6a75352f453c 100644 --- a/arch/s390/kvm/interrupt.c +++ b/arch/s390/kvm/interrupt.c | |||
| @@ -1030,8 +1030,7 @@ static int __inject_extcall(struct kvm_vcpu *vcpu, struct kvm_s390_irq *irq) | |||
| 1030 | src_id, 0); | 1030 | src_id, 0); |
| 1031 | 1031 | ||
| 1032 | /* sending vcpu invalid */ | 1032 | /* sending vcpu invalid */ |
| 1033 | if (src_id >= KVM_MAX_VCPUS || | 1033 | if (kvm_get_vcpu_by_id(vcpu->kvm, src_id) == NULL) |
| 1034 | kvm_get_vcpu(vcpu->kvm, src_id) == NULL) | ||
| 1035 | return -EINVAL; | 1034 | return -EINVAL; |
| 1036 | 1035 | ||
| 1037 | if (sclp.has_sigpif) | 1036 | if (sclp.has_sigpif) |
| @@ -1110,6 +1109,10 @@ static int __inject_sigp_emergency(struct kvm_vcpu *vcpu, | |||
| 1110 | trace_kvm_s390_inject_vcpu(vcpu->vcpu_id, KVM_S390_INT_EMERGENCY, | 1109 | trace_kvm_s390_inject_vcpu(vcpu->vcpu_id, KVM_S390_INT_EMERGENCY, |
| 1111 | irq->u.emerg.code, 0); | 1110 | irq->u.emerg.code, 0); |
| 1112 | 1111 | ||
| 1112 | /* sending vcpu invalid */ | ||
| 1113 | if (kvm_get_vcpu_by_id(vcpu->kvm, irq->u.emerg.code) == NULL) | ||
| 1114 | return -EINVAL; | ||
| 1115 | |||
| 1113 | set_bit(irq->u.emerg.code, li->sigp_emerg_pending); | 1116 | set_bit(irq->u.emerg.code, li->sigp_emerg_pending); |
| 1114 | set_bit(IRQ_PEND_EXT_EMERGENCY, &li->pending_irqs); | 1117 | set_bit(IRQ_PEND_EXT_EMERGENCY, &li->pending_irqs); |
| 1115 | atomic_or(CPUSTAT_EXT_INT, li->cpuflags); | 1118 | atomic_or(CPUSTAT_EXT_INT, li->cpuflags); |
diff --git a/arch/s390/kvm/kvm-s390.c b/arch/s390/kvm/kvm-s390.c index 8fe2f1c722dc..846589281b04 100644 --- a/arch/s390/kvm/kvm-s390.c +++ b/arch/s390/kvm/kvm-s390.c | |||
| @@ -342,12 +342,16 @@ static int kvm_vm_ioctl_enable_cap(struct kvm *kvm, struct kvm_enable_cap *cap) | |||
| 342 | r = 0; | 342 | r = 0; |
| 343 | break; | 343 | break; |
| 344 | case KVM_CAP_S390_VECTOR_REGISTERS: | 344 | case KVM_CAP_S390_VECTOR_REGISTERS: |
| 345 | if (MACHINE_HAS_VX) { | 345 | mutex_lock(&kvm->lock); |
| 346 | if (atomic_read(&kvm->online_vcpus)) { | ||
| 347 | r = -EBUSY; | ||
| 348 | } else if (MACHINE_HAS_VX) { | ||
| 346 | set_kvm_facility(kvm->arch.model.fac->mask, 129); | 349 | set_kvm_facility(kvm->arch.model.fac->mask, 129); |
| 347 | set_kvm_facility(kvm->arch.model.fac->list, 129); | 350 | set_kvm_facility(kvm->arch.model.fac->list, 129); |
| 348 | r = 0; | 351 | r = 0; |
| 349 | } else | 352 | } else |
| 350 | r = -EINVAL; | 353 | r = -EINVAL; |
| 354 | mutex_unlock(&kvm->lock); | ||
| 351 | VM_EVENT(kvm, 3, "ENABLE: CAP_S390_VECTOR_REGISTERS %s", | 355 | VM_EVENT(kvm, 3, "ENABLE: CAP_S390_VECTOR_REGISTERS %s", |
| 352 | r ? "(not available)" : "(success)"); | 356 | r ? "(not available)" : "(success)"); |
| 353 | break; | 357 | break; |
diff --git a/arch/s390/kvm/priv.c b/arch/s390/kvm/priv.c index 77191b85ea7a..d76b51cb4b62 100644 --- a/arch/s390/kvm/priv.c +++ b/arch/s390/kvm/priv.c | |||
| @@ -660,7 +660,7 @@ static int handle_pfmf(struct kvm_vcpu *vcpu) | |||
| 660 | 660 | ||
| 661 | kvm_s390_get_regs_rre(vcpu, ®1, ®2); | 661 | kvm_s390_get_regs_rre(vcpu, ®1, ®2); |
| 662 | 662 | ||
| 663 | if (!MACHINE_HAS_PFMF) | 663 | if (!test_kvm_facility(vcpu->kvm, 8)) |
| 664 | return kvm_s390_inject_program_int(vcpu, PGM_OPERATION); | 664 | return kvm_s390_inject_program_int(vcpu, PGM_OPERATION); |
| 665 | 665 | ||
| 666 | if (vcpu->arch.sie_block->gpsw.mask & PSW_MASK_PSTATE) | 666 | if (vcpu->arch.sie_block->gpsw.mask & PSW_MASK_PSTATE) |
diff --git a/arch/s390/kvm/sigp.c b/arch/s390/kvm/sigp.c index da690b69f9fe..77c22d685c7a 100644 --- a/arch/s390/kvm/sigp.c +++ b/arch/s390/kvm/sigp.c | |||
| @@ -291,12 +291,8 @@ static int handle_sigp_dst(struct kvm_vcpu *vcpu, u8 order_code, | |||
| 291 | u16 cpu_addr, u32 parameter, u64 *status_reg) | 291 | u16 cpu_addr, u32 parameter, u64 *status_reg) |
| 292 | { | 292 | { |
| 293 | int rc; | 293 | int rc; |
| 294 | struct kvm_vcpu *dst_vcpu; | 294 | struct kvm_vcpu *dst_vcpu = kvm_get_vcpu_by_id(vcpu->kvm, cpu_addr); |
| 295 | 295 | ||
| 296 | if (cpu_addr >= KVM_MAX_VCPUS) | ||
| 297 | return SIGP_CC_NOT_OPERATIONAL; | ||
| 298 | |||
| 299 | dst_vcpu = kvm_get_vcpu(vcpu->kvm, cpu_addr); | ||
| 300 | if (!dst_vcpu) | 296 | if (!dst_vcpu) |
| 301 | return SIGP_CC_NOT_OPERATIONAL; | 297 | return SIGP_CC_NOT_OPERATIONAL; |
| 302 | 298 | ||
| @@ -478,7 +474,7 @@ int kvm_s390_handle_sigp_pei(struct kvm_vcpu *vcpu) | |||
| 478 | trace_kvm_s390_handle_sigp_pei(vcpu, order_code, cpu_addr); | 474 | trace_kvm_s390_handle_sigp_pei(vcpu, order_code, cpu_addr); |
| 479 | 475 | ||
| 480 | if (order_code == SIGP_EXTERNAL_CALL) { | 476 | if (order_code == SIGP_EXTERNAL_CALL) { |
| 481 | dest_vcpu = kvm_get_vcpu(vcpu->kvm, cpu_addr); | 477 | dest_vcpu = kvm_get_vcpu_by_id(vcpu->kvm, cpu_addr); |
| 482 | BUG_ON(dest_vcpu == NULL); | 478 | BUG_ON(dest_vcpu == NULL); |
| 483 | 479 | ||
| 484 | kvm_s390_vcpu_wakeup(dest_vcpu); | 480 | kvm_s390_vcpu_wakeup(dest_vcpu); |
diff --git a/include/linux/kvm_host.h b/include/linux/kvm_host.h index 5706a2108f0a..c923350ca20a 100644 --- a/include/linux/kvm_host.h +++ b/include/linux/kvm_host.h | |||
| @@ -460,6 +460,17 @@ static inline struct kvm_vcpu *kvm_get_vcpu(struct kvm *kvm, int i) | |||
| 460 | (vcpup = kvm_get_vcpu(kvm, idx)) != NULL; \ | 460 | (vcpup = kvm_get_vcpu(kvm, idx)) != NULL; \ |
| 461 | idx++) | 461 | idx++) |
| 462 | 462 | ||
| 463 | static inline struct kvm_vcpu *kvm_get_vcpu_by_id(struct kvm *kvm, int id) | ||
| 464 | { | ||
| 465 | struct kvm_vcpu *vcpu; | ||
| 466 | int i; | ||
| 467 | |||
| 468 | kvm_for_each_vcpu(i, vcpu, kvm) | ||
| 469 | if (vcpu->vcpu_id == id) | ||
| 470 | return vcpu; | ||
| 471 | return NULL; | ||
| 472 | } | ||
| 473 | |||
| 463 | #define kvm_for_each_memslot(memslot, slots) \ | 474 | #define kvm_for_each_memslot(memslot, slots) \ |
| 464 | for (memslot = &slots->memslots[0]; \ | 475 | for (memslot = &slots->memslots[0]; \ |
| 465 | memslot < slots->memslots + KVM_MEM_SLOTS_NUM && memslot->npages;\ | 476 | memslot < slots->memslots + KVM_MEM_SLOTS_NUM && memslot->npages;\ |
