interrupt.c (0759d0681cae279e77ebb4b76175e330360b01d9) interrupt.c (4ae3c0815fb63cbed1afcd5bacc7705c6d1b9fec)
1/*
2 * handling kvm guest interrupts
3 *
4 * Copyright IBM Corp. 2008,2014
5 *
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License (version 2 only)
8 * as published by the Free Software Foundation.

--- 530 unchanged lines hidden (view full) ---

539int kvm_cpu_has_interrupt(struct kvm_vcpu *vcpu)
540{
541 struct kvm_s390_local_interrupt *li = &vcpu->arch.local_int;
542 struct kvm_s390_float_interrupt *fi = vcpu->arch.local_int.float_int;
543 struct kvm_s390_interrupt_info *inti;
544 int rc = 0;
545
546 if (atomic_read(&li->active)) {
1/*
2 * handling kvm guest interrupts
3 *
4 * Copyright IBM Corp. 2008,2014
5 *
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License (version 2 only)
8 * as published by the Free Software Foundation.

--- 530 unchanged lines hidden (view full) ---

539int kvm_cpu_has_interrupt(struct kvm_vcpu *vcpu)
540{
541 struct kvm_s390_local_interrupt *li = &vcpu->arch.local_int;
542 struct kvm_s390_float_interrupt *fi = vcpu->arch.local_int.float_int;
543 struct kvm_s390_interrupt_info *inti;
544 int rc = 0;
545
546 if (atomic_read(&li->active)) {
547 spin_lock_bh(&li->lock);
547 spin_lock(&li->lock);
548 list_for_each_entry(inti, &li->list, list)
549 if (__interrupt_is_deliverable(vcpu, inti)) {
550 rc = 1;
551 break;
552 }
548 list_for_each_entry(inti, &li->list, list)
549 if (__interrupt_is_deliverable(vcpu, inti)) {
550 rc = 1;
551 break;
552 }
553 spin_unlock_bh(&li->lock);
553 spin_unlock(&li->lock);
554 }
555
556 if ((!rc) && atomic_read(&fi->active)) {
557 spin_lock(&fi->lock);
558 list_for_each_entry(inti, &fi->list, list)
559 if (__interrupt_is_deliverable(vcpu, inti)) {
560 rc = 1;
561 break;

--- 78 unchanged lines hidden (view full) ---

640 return HRTIMER_NORESTART;
641}
642
643void kvm_s390_clear_local_irqs(struct kvm_vcpu *vcpu)
644{
645 struct kvm_s390_local_interrupt *li = &vcpu->arch.local_int;
646 struct kvm_s390_interrupt_info *n, *inti = NULL;
647
554 }
555
556 if ((!rc) && atomic_read(&fi->active)) {
557 spin_lock(&fi->lock);
558 list_for_each_entry(inti, &fi->list, list)
559 if (__interrupt_is_deliverable(vcpu, inti)) {
560 rc = 1;
561 break;

--- 78 unchanged lines hidden (view full) ---

640 return HRTIMER_NORESTART;
641}
642
643void kvm_s390_clear_local_irqs(struct kvm_vcpu *vcpu)
644{
645 struct kvm_s390_local_interrupt *li = &vcpu->arch.local_int;
646 struct kvm_s390_interrupt_info *n, *inti = NULL;
647
648 spin_lock_bh(&li->lock);
648 spin_lock(&li->lock);
649 list_for_each_entry_safe(inti, n, &li->list, list) {
650 list_del(&inti->list);
651 kfree(inti);
652 }
653 atomic_set(&li->active, 0);
649 list_for_each_entry_safe(inti, n, &li->list, list) {
650 list_del(&inti->list);
651 kfree(inti);
652 }
653 atomic_set(&li->active, 0);
654 spin_unlock_bh(&li->lock);
654 spin_unlock(&li->lock);
655
656 /* clear pending external calls set by sigp interpretation facility */
657 atomic_clear_mask(CPUSTAT_ECALL_PEND, &vcpu->arch.sie_block->cpuflags);
658 atomic_clear_mask(SIGP_CTRL_C,
659 &vcpu->kvm->arch.sca->cpu[vcpu->vcpu_id].ctrl);
660}
661
662void kvm_s390_deliver_pending_interrupts(struct kvm_vcpu *vcpu)
663{
664 struct kvm_s390_local_interrupt *li = &vcpu->arch.local_int;
665 struct kvm_s390_float_interrupt *fi = vcpu->arch.local_int.float_int;
666 struct kvm_s390_interrupt_info *n, *inti = NULL;
667 int deliver;
668
669 __reset_intercept_indicators(vcpu);
670 if (atomic_read(&li->active)) {
671 do {
672 deliver = 0;
655
656 /* clear pending external calls set by sigp interpretation facility */
657 atomic_clear_mask(CPUSTAT_ECALL_PEND, &vcpu->arch.sie_block->cpuflags);
658 atomic_clear_mask(SIGP_CTRL_C,
659 &vcpu->kvm->arch.sca->cpu[vcpu->vcpu_id].ctrl);
660}
661
662void kvm_s390_deliver_pending_interrupts(struct kvm_vcpu *vcpu)
663{
664 struct kvm_s390_local_interrupt *li = &vcpu->arch.local_int;
665 struct kvm_s390_float_interrupt *fi = vcpu->arch.local_int.float_int;
666 struct kvm_s390_interrupt_info *n, *inti = NULL;
667 int deliver;
668
669 __reset_intercept_indicators(vcpu);
670 if (atomic_read(&li->active)) {
671 do {
672 deliver = 0;
673 spin_lock_bh(&li->lock);
673 spin_lock(&li->lock);
674 list_for_each_entry_safe(inti, n, &li->list, list) {
675 if (__interrupt_is_deliverable(vcpu, inti)) {
676 list_del(&inti->list);
677 deliver = 1;
678 break;
679 }
680 __set_intercept_indicator(vcpu, inti);
681 }
682 if (list_empty(&li->list))
683 atomic_set(&li->active, 0);
674 list_for_each_entry_safe(inti, n, &li->list, list) {
675 if (__interrupt_is_deliverable(vcpu, inti)) {
676 list_del(&inti->list);
677 deliver = 1;
678 break;
679 }
680 __set_intercept_indicator(vcpu, inti);
681 }
682 if (list_empty(&li->list))
683 atomic_set(&li->active, 0);
684 spin_unlock_bh(&li->lock);
684 spin_unlock(&li->lock);
685 if (deliver) {
686 __do_deliver_interrupt(vcpu, inti);
687 kfree(inti);
688 }
689 } while (deliver);
690 }
691
692 if (kvm_cpu_has_pending_timer(vcpu))

--- 29 unchanged lines hidden (view full) ---

722 struct kvm_s390_float_interrupt *fi = vcpu->arch.local_int.float_int;
723 struct kvm_s390_interrupt_info *n, *inti = NULL;
724 int deliver;
725
726 __reset_intercept_indicators(vcpu);
727 if (atomic_read(&li->active)) {
728 do {
729 deliver = 0;
685 if (deliver) {
686 __do_deliver_interrupt(vcpu, inti);
687 kfree(inti);
688 }
689 } while (deliver);
690 }
691
692 if (kvm_cpu_has_pending_timer(vcpu))

--- 29 unchanged lines hidden (view full) ---

722 struct kvm_s390_float_interrupt *fi = vcpu->arch.local_int.float_int;
723 struct kvm_s390_interrupt_info *n, *inti = NULL;
724 int deliver;
725
726 __reset_intercept_indicators(vcpu);
727 if (atomic_read(&li->active)) {
728 do {
729 deliver = 0;
730 spin_lock_bh(&li->lock);
730 spin_lock(&li->lock);
731 list_for_each_entry_safe(inti, n, &li->list, list) {
732 if ((inti->type == KVM_S390_MCHK) &&
733 __interrupt_is_deliverable(vcpu, inti)) {
734 list_del(&inti->list);
735 deliver = 1;
736 break;
737 }
738 __set_intercept_indicator(vcpu, inti);
739 }
740 if (list_empty(&li->list))
741 atomic_set(&li->active, 0);
731 list_for_each_entry_safe(inti, n, &li->list, list) {
732 if ((inti->type == KVM_S390_MCHK) &&
733 __interrupt_is_deliverable(vcpu, inti)) {
734 list_del(&inti->list);
735 deliver = 1;
736 break;
737 }
738 __set_intercept_indicator(vcpu, inti);
739 }
740 if (list_empty(&li->list))
741 atomic_set(&li->active, 0);
742 spin_unlock_bh(&li->lock);
742 spin_unlock(&li->lock);
743 if (deliver) {
744 __do_deliver_interrupt(vcpu, inti);
745 kfree(inti);
746 }
747 } while (deliver);
748 }
749
750 if (atomic_read(&fi->active)) {

--- 30 unchanged lines hidden (view full) ---

781 if (!inti)
782 return -ENOMEM;
783
784 inti->type = KVM_S390_PROGRAM_INT;
785 inti->pgm.code = code;
786
787 VCPU_EVENT(vcpu, 3, "inject: program check %d (from kernel)", code);
788 trace_kvm_s390_inject_vcpu(vcpu->vcpu_id, inti->type, code, 0, 1);
743 if (deliver) {
744 __do_deliver_interrupt(vcpu, inti);
745 kfree(inti);
746 }
747 } while (deliver);
748 }
749
750 if (atomic_read(&fi->active)) {

--- 30 unchanged lines hidden (view full) ---

781 if (!inti)
782 return -ENOMEM;
783
784 inti->type = KVM_S390_PROGRAM_INT;
785 inti->pgm.code = code;
786
787 VCPU_EVENT(vcpu, 3, "inject: program check %d (from kernel)", code);
788 trace_kvm_s390_inject_vcpu(vcpu->vcpu_id, inti->type, code, 0, 1);
789 spin_lock_bh(&li->lock);
789 spin_lock(&li->lock);
790 list_add(&inti->list, &li->list);
791 atomic_set(&li->active, 1);
792 BUG_ON(waitqueue_active(li->wq));
790 list_add(&inti->list, &li->list);
791 atomic_set(&li->active, 1);
792 BUG_ON(waitqueue_active(li->wq));
793 spin_unlock_bh(&li->lock);
793 spin_unlock(&li->lock);
794 return 0;
795}
796
797int kvm_s390_inject_prog_irq(struct kvm_vcpu *vcpu,
798 struct kvm_s390_pgm_info *pgm_info)
799{
800 struct kvm_s390_local_interrupt *li = &vcpu->arch.local_int;
801 struct kvm_s390_interrupt_info *inti;

--- 4 unchanged lines hidden (view full) ---

806
807 VCPU_EVENT(vcpu, 3, "inject: prog irq %d (from kernel)",
808 pgm_info->code);
809 trace_kvm_s390_inject_vcpu(vcpu->vcpu_id, KVM_S390_PROGRAM_INT,
810 pgm_info->code, 0, 1);
811
812 inti->type = KVM_S390_PROGRAM_INT;
813 memcpy(&inti->pgm, pgm_info, sizeof(inti->pgm));
794 return 0;
795}
796
797int kvm_s390_inject_prog_irq(struct kvm_vcpu *vcpu,
798 struct kvm_s390_pgm_info *pgm_info)
799{
800 struct kvm_s390_local_interrupt *li = &vcpu->arch.local_int;
801 struct kvm_s390_interrupt_info *inti;

--- 4 unchanged lines hidden (view full) ---

806
807 VCPU_EVENT(vcpu, 3, "inject: prog irq %d (from kernel)",
808 pgm_info->code);
809 trace_kvm_s390_inject_vcpu(vcpu->vcpu_id, KVM_S390_PROGRAM_INT,
810 pgm_info->code, 0, 1);
811
812 inti->type = KVM_S390_PROGRAM_INT;
813 memcpy(&inti->pgm, pgm_info, sizeof(inti->pgm));
814 spin_lock_bh(&li->lock);
814 spin_lock(&li->lock);
815 list_add(&inti->list, &li->list);
816 atomic_set(&li->active, 1);
817 BUG_ON(waitqueue_active(li->wq));
815 list_add(&inti->list, &li->list);
816 atomic_set(&li->active, 1);
817 BUG_ON(waitqueue_active(li->wq));
818 spin_unlock_bh(&li->lock);
818 spin_unlock(&li->lock);
819 return 0;
820}
821
822struct kvm_s390_interrupt_info *kvm_s390_get_io_int(struct kvm *kvm,
823 u64 cr6, u64 schid)
824{
825 struct kvm_s390_float_interrupt *fi;
826 struct kvm_s390_interrupt_info *inti, *iter;

--- 71 unchanged lines hidden (view full) ---

898 do {
899 sigcpu = fi->next_rr_cpu++;
900 if (sigcpu == KVM_MAX_VCPUS)
901 sigcpu = fi->next_rr_cpu = 0;
902 } while (kvm_get_vcpu(kvm, sigcpu) == NULL);
903 }
904 dst_vcpu = kvm_get_vcpu(kvm, sigcpu);
905 li = &dst_vcpu->arch.local_int;
819 return 0;
820}
821
822struct kvm_s390_interrupt_info *kvm_s390_get_io_int(struct kvm *kvm,
823 u64 cr6, u64 schid)
824{
825 struct kvm_s390_float_interrupt *fi;
826 struct kvm_s390_interrupt_info *inti, *iter;

--- 71 unchanged lines hidden (view full) ---

898 do {
899 sigcpu = fi->next_rr_cpu++;
900 if (sigcpu == KVM_MAX_VCPUS)
901 sigcpu = fi->next_rr_cpu = 0;
902 } while (kvm_get_vcpu(kvm, sigcpu) == NULL);
903 }
904 dst_vcpu = kvm_get_vcpu(kvm, sigcpu);
905 li = &dst_vcpu->arch.local_int;
906 spin_lock_bh(&li->lock);
906 spin_lock(&li->lock);
907 atomic_set_mask(CPUSTAT_EXT_INT, li->cpuflags);
908 if (waitqueue_active(li->wq))
909 wake_up_interruptible(li->wq);
910 kvm_get_vcpu(kvm, sigcpu)->preempted = true;
907 atomic_set_mask(CPUSTAT_EXT_INT, li->cpuflags);
908 if (waitqueue_active(li->wq))
909 wake_up_interruptible(li->wq);
910 kvm_get_vcpu(kvm, sigcpu)->preempted = true;
911 spin_unlock_bh(&li->lock);
911 spin_unlock(&li->lock);
912unlock_fi:
913 spin_unlock(&fi->lock);
914 mutex_unlock(&kvm->lock);
915 return rc;
916}
917
918int kvm_s390_inject_vm(struct kvm *kvm,
919 struct kvm_s390_interrupt *s390int)

--- 125 unchanged lines hidden (view full) ---

1045 kfree(inti);
1046 return -EINVAL;
1047 }
1048 trace_kvm_s390_inject_vcpu(vcpu->vcpu_id, s390int->type, s390int->parm,
1049 s390int->parm64, 2);
1050
1051 mutex_lock(&vcpu->kvm->lock);
1052 li = &vcpu->arch.local_int;
912unlock_fi:
913 spin_unlock(&fi->lock);
914 mutex_unlock(&kvm->lock);
915 return rc;
916}
917
918int kvm_s390_inject_vm(struct kvm *kvm,
919 struct kvm_s390_interrupt *s390int)

--- 125 unchanged lines hidden (view full) ---

1045 kfree(inti);
1046 return -EINVAL;
1047 }
1048 trace_kvm_s390_inject_vcpu(vcpu->vcpu_id, s390int->type, s390int->parm,
1049 s390int->parm64, 2);
1050
1051 mutex_lock(&vcpu->kvm->lock);
1052 li = &vcpu->arch.local_int;
1053 spin_lock_bh(&li->lock);
1053 spin_lock(&li->lock);
1054 if (inti->type == KVM_S390_PROGRAM_INT)
1055 list_add(&inti->list, &li->list);
1056 else
1057 list_add_tail(&inti->list, &li->list);
1058 atomic_set(&li->active, 1);
1059 if (inti->type == KVM_S390_SIGP_STOP)
1060 li->action_bits |= ACTION_STOP_ON_STOP;
1061 atomic_set_mask(CPUSTAT_EXT_INT, li->cpuflags);
1062 if (waitqueue_active(&vcpu->wq))
1063 wake_up_interruptible(&vcpu->wq);
1064 vcpu->preempted = true;
1054 if (inti->type == KVM_S390_PROGRAM_INT)
1055 list_add(&inti->list, &li->list);
1056 else
1057 list_add_tail(&inti->list, &li->list);
1058 atomic_set(&li->active, 1);
1059 if (inti->type == KVM_S390_SIGP_STOP)
1060 li->action_bits |= ACTION_STOP_ON_STOP;
1061 atomic_set_mask(CPUSTAT_EXT_INT, li->cpuflags);
1062 if (waitqueue_active(&vcpu->wq))
1063 wake_up_interruptible(&vcpu->wq);
1064 vcpu->preempted = true;
1065 spin_unlock_bh(&li->lock);
1065 spin_unlock(&li->lock);
1066 mutex_unlock(&vcpu->kvm->lock);
1067 return 0;
1068}
1069
1070void kvm_s390_clear_float_irqs(struct kvm *kvm)
1071{
1072 struct kvm_s390_float_interrupt *fi;
1073 struct kvm_s390_interrupt_info *n, *inti = NULL;

--- 515 unchanged lines hidden ---
1066 mutex_unlock(&vcpu->kvm->lock);
1067 return 0;
1068}
1069
1070void kvm_s390_clear_float_irqs(struct kvm *kvm)
1071{
1072 struct kvm_s390_float_interrupt *fi;
1073 struct kvm_s390_interrupt_info *n, *inti = NULL;

--- 515 unchanged lines hidden ---