diff options
| -rw-r--r-- | arch/s390/include/asm/kvm_host.h | 6 | ||||
| -rw-r--r-- | arch/s390/kvm/interrupt.c | 52 | ||||
| -rw-r--r-- | arch/s390/kvm/kvm-s390.c | 2 |
3 files changed, 36 insertions, 24 deletions
diff --git a/arch/s390/include/asm/kvm_host.h b/arch/s390/include/asm/kvm_host.h index c259a67c4298..0941571d34eb 100644 --- a/arch/s390/include/asm/kvm_host.h +++ b/arch/s390/include/asm/kvm_host.h | |||
| @@ -803,6 +803,10 @@ struct kvm_s390_vsie { | |||
| 803 | struct page *pages[KVM_MAX_VCPUS]; | 803 | struct page *pages[KVM_MAX_VCPUS]; |
| 804 | }; | 804 | }; |
| 805 | 805 | ||
| 806 | struct kvm_s390_gisa_interrupt { | ||
| 807 | struct kvm_s390_gisa *origin; | ||
| 808 | }; | ||
| 809 | |||
| 806 | struct kvm_arch{ | 810 | struct kvm_arch{ |
| 807 | void *sca; | 811 | void *sca; |
| 808 | int use_esca; | 812 | int use_esca; |
| @@ -836,8 +840,8 @@ struct kvm_arch{ | |||
| 836 | atomic64_t cmma_dirty_pages; | 840 | atomic64_t cmma_dirty_pages; |
| 837 | /* subset of available cpu features enabled by user space */ | 841 | /* subset of available cpu features enabled by user space */ |
| 838 | DECLARE_BITMAP(cpu_feat, KVM_S390_VM_CPU_FEAT_NR_BITS); | 842 | DECLARE_BITMAP(cpu_feat, KVM_S390_VM_CPU_FEAT_NR_BITS); |
| 839 | struct kvm_s390_gisa *gisa; | ||
| 840 | DECLARE_BITMAP(idle_mask, KVM_MAX_VCPUS); | 843 | DECLARE_BITMAP(idle_mask, KVM_MAX_VCPUS); |
| 844 | struct kvm_s390_gisa_interrupt gisa_int; | ||
| 841 | }; | 845 | }; |
| 842 | 846 | ||
| 843 | #define KVM_HVA_ERR_BAD (-1UL) | 847 | #define KVM_HVA_ERR_BAD (-1UL) |
diff --git a/arch/s390/kvm/interrupt.c b/arch/s390/kvm/interrupt.c index 942cc7d33766..ee91d1de0036 100644 --- a/arch/s390/kvm/interrupt.c +++ b/arch/s390/kvm/interrupt.c | |||
| @@ -246,7 +246,8 @@ static inline unsigned long pending_irqs_no_gisa(struct kvm_vcpu *vcpu) | |||
| 246 | static inline unsigned long pending_irqs(struct kvm_vcpu *vcpu) | 246 | static inline unsigned long pending_irqs(struct kvm_vcpu *vcpu) |
| 247 | { | 247 | { |
| 248 | return pending_irqs_no_gisa(vcpu) | | 248 | return pending_irqs_no_gisa(vcpu) | |
| 249 | gisa_get_ipm(vcpu->kvm->arch.gisa) << IRQ_PEND_IO_ISC_7; | 249 | gisa_get_ipm(vcpu->kvm->arch.gisa_int.origin) << |
| 250 | IRQ_PEND_IO_ISC_7; | ||
| 250 | } | 251 | } |
| 251 | 252 | ||
| 252 | static inline int isc_to_irq_type(unsigned long isc) | 253 | static inline int isc_to_irq_type(unsigned long isc) |
| @@ -956,6 +957,7 @@ static int __must_check __deliver_io(struct kvm_vcpu *vcpu, | |||
| 956 | { | 957 | { |
| 957 | struct list_head *isc_list; | 958 | struct list_head *isc_list; |
| 958 | struct kvm_s390_float_interrupt *fi; | 959 | struct kvm_s390_float_interrupt *fi; |
| 960 | struct kvm_s390_gisa_interrupt *gi = &vcpu->kvm->arch.gisa_int; | ||
| 959 | struct kvm_s390_interrupt_info *inti = NULL; | 961 | struct kvm_s390_interrupt_info *inti = NULL; |
| 960 | struct kvm_s390_io_info io; | 962 | struct kvm_s390_io_info io; |
| 961 | u32 isc; | 963 | u32 isc; |
| @@ -998,8 +1000,7 @@ static int __must_check __deliver_io(struct kvm_vcpu *vcpu, | |||
| 998 | goto out; | 1000 | goto out; |
| 999 | } | 1001 | } |
| 1000 | 1002 | ||
| 1001 | if (vcpu->kvm->arch.gisa && | 1003 | if (gi->origin && gisa_tac_ipm_gisc(gi->origin, isc)) { |
| 1002 | gisa_tac_ipm_gisc(vcpu->kvm->arch.gisa, isc)) { | ||
| 1003 | /* | 1004 | /* |
| 1004 | * in case an adapter interrupt was not delivered | 1005 | * in case an adapter interrupt was not delivered |
| 1005 | * in SIE context KVM will handle the delivery | 1006 | * in SIE context KVM will handle the delivery |
| @@ -1533,18 +1534,19 @@ static struct kvm_s390_interrupt_info *get_top_io_int(struct kvm *kvm, | |||
| 1533 | 1534 | ||
| 1534 | static int get_top_gisa_isc(struct kvm *kvm, u64 isc_mask, u32 schid) | 1535 | static int get_top_gisa_isc(struct kvm *kvm, u64 isc_mask, u32 schid) |
| 1535 | { | 1536 | { |
| 1537 | struct kvm_s390_gisa_interrupt *gi = &kvm->arch.gisa_int; | ||
| 1536 | unsigned long active_mask; | 1538 | unsigned long active_mask; |
| 1537 | int isc; | 1539 | int isc; |
| 1538 | 1540 | ||
| 1539 | if (schid) | 1541 | if (schid) |
| 1540 | goto out; | 1542 | goto out; |
| 1541 | if (!kvm->arch.gisa) | 1543 | if (!gi->origin) |
| 1542 | goto out; | 1544 | goto out; |
| 1543 | 1545 | ||
| 1544 | active_mask = (isc_mask & gisa_get_ipm(kvm->arch.gisa) << 24) << 32; | 1546 | active_mask = (isc_mask & gisa_get_ipm(gi->origin) << 24) << 32; |
| 1545 | while (active_mask) { | 1547 | while (active_mask) { |
| 1546 | isc = __fls(active_mask) ^ (BITS_PER_LONG - 1); | 1548 | isc = __fls(active_mask) ^ (BITS_PER_LONG - 1); |
| 1547 | if (gisa_tac_ipm_gisc(kvm->arch.gisa, isc)) | 1549 | if (gisa_tac_ipm_gisc(gi->origin, isc)) |
| 1548 | return isc; | 1550 | return isc; |
| 1549 | clear_bit_inv(isc, &active_mask); | 1551 | clear_bit_inv(isc, &active_mask); |
| 1550 | } | 1552 | } |
| @@ -1567,6 +1569,7 @@ out: | |||
| 1567 | struct kvm_s390_interrupt_info *kvm_s390_get_io_int(struct kvm *kvm, | 1569 | struct kvm_s390_interrupt_info *kvm_s390_get_io_int(struct kvm *kvm, |
| 1568 | u64 isc_mask, u32 schid) | 1570 | u64 isc_mask, u32 schid) |
| 1569 | { | 1571 | { |
| 1572 | struct kvm_s390_gisa_interrupt *gi = &kvm->arch.gisa_int; | ||
| 1570 | struct kvm_s390_interrupt_info *inti, *tmp_inti; | 1573 | struct kvm_s390_interrupt_info *inti, *tmp_inti; |
| 1571 | int isc; | 1574 | int isc; |
| 1572 | 1575 | ||
| @@ -1584,7 +1587,7 @@ struct kvm_s390_interrupt_info *kvm_s390_get_io_int(struct kvm *kvm, | |||
| 1584 | /* both types of interrupts present */ | 1587 | /* both types of interrupts present */ |
| 1585 | if (int_word_to_isc(inti->io.io_int_word) <= isc) { | 1588 | if (int_word_to_isc(inti->io.io_int_word) <= isc) { |
| 1586 | /* classical IO int with higher priority */ | 1589 | /* classical IO int with higher priority */ |
| 1587 | gisa_set_ipm_gisc(kvm->arch.gisa, isc); | 1590 | gisa_set_ipm_gisc(gi->origin, isc); |
| 1588 | goto out; | 1591 | goto out; |
| 1589 | } | 1592 | } |
| 1590 | gisa_out: | 1593 | gisa_out: |
| @@ -1596,7 +1599,7 @@ gisa_out: | |||
| 1596 | kvm_s390_reinject_io_int(kvm, inti); | 1599 | kvm_s390_reinject_io_int(kvm, inti); |
| 1597 | inti = tmp_inti; | 1600 | inti = tmp_inti; |
| 1598 | } else | 1601 | } else |
| 1599 | gisa_set_ipm_gisc(kvm->arch.gisa, isc); | 1602 | gisa_set_ipm_gisc(gi->origin, isc); |
| 1600 | out: | 1603 | out: |
| 1601 | return inti; | 1604 | return inti; |
| 1602 | } | 1605 | } |
| @@ -1685,6 +1688,7 @@ static int __inject_float_mchk(struct kvm *kvm, | |||
| 1685 | 1688 | ||
| 1686 | static int __inject_io(struct kvm *kvm, struct kvm_s390_interrupt_info *inti) | 1689 | static int __inject_io(struct kvm *kvm, struct kvm_s390_interrupt_info *inti) |
| 1687 | { | 1690 | { |
| 1691 | struct kvm_s390_gisa_interrupt *gi = &kvm->arch.gisa_int; | ||
| 1688 | struct kvm_s390_float_interrupt *fi; | 1692 | struct kvm_s390_float_interrupt *fi; |
| 1689 | struct list_head *list; | 1693 | struct list_head *list; |
| 1690 | int isc; | 1694 | int isc; |
| @@ -1692,9 +1696,9 @@ static int __inject_io(struct kvm *kvm, struct kvm_s390_interrupt_info *inti) | |||
| 1692 | kvm->stat.inject_io++; | 1696 | kvm->stat.inject_io++; |
| 1693 | isc = int_word_to_isc(inti->io.io_int_word); | 1697 | isc = int_word_to_isc(inti->io.io_int_word); |
| 1694 | 1698 | ||
| 1695 | if (kvm->arch.gisa && inti->type & KVM_S390_INT_IO_AI_MASK) { | 1699 | if (gi->origin && inti->type & KVM_S390_INT_IO_AI_MASK) { |
| 1696 | VM_EVENT(kvm, 4, "%s isc %1u", "inject: I/O (AI/gisa)", isc); | 1700 | VM_EVENT(kvm, 4, "%s isc %1u", "inject: I/O (AI/gisa)", isc); |
| 1697 | gisa_set_ipm_gisc(kvm->arch.gisa, isc); | 1701 | gisa_set_ipm_gisc(gi->origin, isc); |
| 1698 | kfree(inti); | 1702 | kfree(inti); |
| 1699 | return 0; | 1703 | return 0; |
| 1700 | } | 1704 | } |
| @@ -1752,7 +1756,8 @@ static void __floating_irq_kick(struct kvm *kvm, u64 type) | |||
| 1752 | kvm_s390_set_cpuflags(dst_vcpu, CPUSTAT_STOP_INT); | 1756 | kvm_s390_set_cpuflags(dst_vcpu, CPUSTAT_STOP_INT); |
| 1753 | break; | 1757 | break; |
| 1754 | case KVM_S390_INT_IO_MIN...KVM_S390_INT_IO_MAX: | 1758 | case KVM_S390_INT_IO_MIN...KVM_S390_INT_IO_MAX: |
| 1755 | if (!(type & KVM_S390_INT_IO_AI_MASK && kvm->arch.gisa)) | 1759 | if (!(type & KVM_S390_INT_IO_AI_MASK && |
| 1760 | kvm->arch.gisa_int.origin)) | ||
| 1756 | kvm_s390_set_cpuflags(dst_vcpu, CPUSTAT_IO_INT); | 1761 | kvm_s390_set_cpuflags(dst_vcpu, CPUSTAT_IO_INT); |
| 1757 | break; | 1762 | break; |
| 1758 | default: | 1763 | default: |
| @@ -2002,6 +2007,7 @@ void kvm_s390_clear_float_irqs(struct kvm *kvm) | |||
| 2002 | 2007 | ||
| 2003 | static int get_all_floating_irqs(struct kvm *kvm, u8 __user *usrbuf, u64 len) | 2008 | static int get_all_floating_irqs(struct kvm *kvm, u8 __user *usrbuf, u64 len) |
| 2004 | { | 2009 | { |
| 2010 | struct kvm_s390_gisa_interrupt *gi = &kvm->arch.gisa_int; | ||
| 2005 | struct kvm_s390_interrupt_info *inti; | 2011 | struct kvm_s390_interrupt_info *inti; |
| 2006 | struct kvm_s390_float_interrupt *fi; | 2012 | struct kvm_s390_float_interrupt *fi; |
| 2007 | struct kvm_s390_irq *buf; | 2013 | struct kvm_s390_irq *buf; |
| @@ -2025,14 +2031,14 @@ static int get_all_floating_irqs(struct kvm *kvm, u8 __user *usrbuf, u64 len) | |||
| 2025 | 2031 | ||
| 2026 | max_irqs = len / sizeof(struct kvm_s390_irq); | 2032 | max_irqs = len / sizeof(struct kvm_s390_irq); |
| 2027 | 2033 | ||
| 2028 | if (kvm->arch.gisa && gisa_get_ipm(kvm->arch.gisa)) { | 2034 | if (gi->origin && gisa_get_ipm(gi->origin)) { |
| 2029 | for (i = 0; i <= MAX_ISC; i++) { | 2035 | for (i = 0; i <= MAX_ISC; i++) { |
| 2030 | if (n == max_irqs) { | 2036 | if (n == max_irqs) { |
| 2031 | /* signal userspace to try again */ | 2037 | /* signal userspace to try again */ |
| 2032 | ret = -ENOMEM; | 2038 | ret = -ENOMEM; |
| 2033 | goto out_nolock; | 2039 | goto out_nolock; |
| 2034 | } | 2040 | } |
| 2035 | if (gisa_tac_ipm_gisc(kvm->arch.gisa, i)) { | 2041 | if (gisa_tac_ipm_gisc(gi->origin, i)) { |
| 2036 | irq = (struct kvm_s390_irq *) &buf[n]; | 2042 | irq = (struct kvm_s390_irq *) &buf[n]; |
| 2037 | irq->type = KVM_S390_INT_IO(1, 0, 0, 0); | 2043 | irq->type = KVM_S390_INT_IO(1, 0, 0, 0); |
| 2038 | irq->u.io.io_int_word = isc_to_int_word(i); | 2044 | irq->u.io.io_int_word = isc_to_int_word(i); |
| @@ -2884,25 +2890,27 @@ int kvm_s390_get_irq_state(struct kvm_vcpu *vcpu, __u8 __user *buf, int len) | |||
| 2884 | 2890 | ||
| 2885 | void kvm_s390_gisa_clear(struct kvm *kvm) | 2891 | void kvm_s390_gisa_clear(struct kvm *kvm) |
| 2886 | { | 2892 | { |
| 2887 | if (!kvm->arch.gisa) | 2893 | struct kvm_s390_gisa_interrupt *gi = &kvm->arch.gisa_int; |
| 2894 | |||
| 2895 | if (!gi->origin) | ||
| 2888 | return; | 2896 | return; |
| 2889 | memset(kvm->arch.gisa, 0, sizeof(struct kvm_s390_gisa)); | 2897 | memset(gi->origin, 0, sizeof(struct kvm_s390_gisa)); |
| 2890 | kvm->arch.gisa->next_alert = (u32)(u64)kvm->arch.gisa; | 2898 | gi->origin->next_alert = (u32)(u64)gi->origin; |
| 2891 | VM_EVENT(kvm, 3, "gisa 0x%pK cleared", kvm->arch.gisa); | 2899 | VM_EVENT(kvm, 3, "gisa 0x%pK cleared", gi->origin); |
| 2892 | } | 2900 | } |
| 2893 | 2901 | ||
| 2894 | void kvm_s390_gisa_init(struct kvm *kvm) | 2902 | void kvm_s390_gisa_init(struct kvm *kvm) |
| 2895 | { | 2903 | { |
| 2904 | struct kvm_s390_gisa_interrupt *gi = &kvm->arch.gisa_int; | ||
| 2905 | |||
| 2896 | if (!css_general_characteristics.aiv) | 2906 | if (!css_general_characteristics.aiv) |
| 2897 | return; | 2907 | return; |
| 2898 | kvm->arch.gisa = &kvm->arch.sie_page2->gisa; | 2908 | gi->origin = &kvm->arch.sie_page2->gisa; |
| 2899 | kvm_s390_gisa_clear(kvm); | 2909 | kvm_s390_gisa_clear(kvm); |
| 2900 | VM_EVENT(kvm, 3, "gisa 0x%pK initialized", kvm->arch.gisa); | 2910 | VM_EVENT(kvm, 3, "gisa 0x%pK initialized", gi->origin); |
| 2901 | } | 2911 | } |
| 2902 | 2912 | ||
| 2903 | void kvm_s390_gisa_destroy(struct kvm *kvm) | 2913 | void kvm_s390_gisa_destroy(struct kvm *kvm) |
| 2904 | { | 2914 | { |
| 2905 | if (!kvm->arch.gisa) | 2915 | kvm->arch.gisa_int.origin = NULL; |
| 2906 | return; | ||
| 2907 | kvm->arch.gisa = NULL; | ||
| 2908 | } | 2916 | } |
diff --git a/arch/s390/kvm/kvm-s390.c b/arch/s390/kvm/kvm-s390.c index 11b4be3dad15..5eaffb3e1738 100644 --- a/arch/s390/kvm/kvm-s390.c +++ b/arch/s390/kvm/kvm-s390.c | |||
| @@ -2812,7 +2812,7 @@ struct kvm_vcpu *kvm_arch_vcpu_create(struct kvm *kvm, | |||
| 2812 | 2812 | ||
| 2813 | vcpu->arch.sie_block->icpua = id; | 2813 | vcpu->arch.sie_block->icpua = id; |
| 2814 | spin_lock_init(&vcpu->arch.local_int.lock); | 2814 | spin_lock_init(&vcpu->arch.local_int.lock); |
| 2815 | vcpu->arch.sie_block->gd = (u32)(u64)kvm->arch.gisa; | 2815 | vcpu->arch.sie_block->gd = (u32)(u64)kvm->arch.gisa_int.origin; |
| 2816 | if (vcpu->arch.sie_block->gd && sclp.has_gisaf) | 2816 | if (vcpu->arch.sie_block->gd && sclp.has_gisaf) |
| 2817 | vcpu->arch.sie_block->gd |= GISA_FORMAT1; | 2817 | vcpu->arch.sie_block->gd |= GISA_FORMAT1; |
| 2818 | seqcount_init(&vcpu->arch.cputm_seqcount); | 2818 | seqcount_init(&vcpu->arch.cputm_seqcount); |
