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 --- |