diff options
author | Michael Mueller <mimu@linux.vnet.ibm.com> | 2017-06-14 07:21:32 -0400 |
---|---|---|
committer | Christian Borntraeger <borntraeger@de.ibm.com> | 2018-01-26 05:12:10 -0500 |
commit | 24160af6cb289ace9bde980b33d11713c8fc8192 (patch) | |
tree | 7207729d4e4a8e0e0abd458e9651698bdfc4220c | |
parent | 2496c8e7fe9270bde5e125729c193120e7fa8c67 (diff) |
KVM: s390: add GISA interrupts to FLIC ioctl interface
Pending interrupts marked in the GISA IPM are required to
become part of the answer of ioctl KVM_DEV_FLIC_GET_ALL_IRQS.
The ioctl KVM_DEV_FLIC_ENQUEUE is already capable to enqueue
adapter interrupts when a GISA is present.
With ioctl KVM_DEV_FLIC_CLEAR_IRQS the GISA IPM wil be cleared
now as well.
Signed-off-by: Michael Mueller <mimu@linux.vnet.ibm.com>
Reviewed-by: Halil Pasic <pasic@linux.vnet.ibm.com>
Reviewed-by: Pierre Morel <pmorel@linux.vnet.ibm.com>
Reviewed-by: Christian Borntraeger <borntraeger@de.ibm.com>
Reviewed-by: Cornelia Huck <cohuck@redhat.com>
Signed-off-by: Christian Borntraeger <borntraeger@de.ibm.com>
-rw-r--r-- | arch/s390/kvm/interrupt.c | 18 |
1 files changed, 18 insertions, 0 deletions
diff --git a/arch/s390/kvm/interrupt.c b/arch/s390/kvm/interrupt.c index a0ded3a23a5e..dd4c50b82a53 100644 --- a/arch/s390/kvm/interrupt.c +++ b/arch/s390/kvm/interrupt.c | |||
@@ -1879,6 +1879,7 @@ void kvm_s390_clear_float_irqs(struct kvm *kvm) | |||
1879 | for (i = 0; i < FIRQ_MAX_COUNT; i++) | 1879 | for (i = 0; i < FIRQ_MAX_COUNT; i++) |
1880 | fi->counters[i] = 0; | 1880 | fi->counters[i] = 0; |
1881 | spin_unlock(&fi->lock); | 1881 | spin_unlock(&fi->lock); |
1882 | kvm_s390_gisa_clear(kvm); | ||
1882 | }; | 1883 | }; |
1883 | 1884 | ||
1884 | static int get_all_floating_irqs(struct kvm *kvm, u8 __user *usrbuf, u64 len) | 1885 | static int get_all_floating_irqs(struct kvm *kvm, u8 __user *usrbuf, u64 len) |
@@ -1906,6 +1907,22 @@ static int get_all_floating_irqs(struct kvm *kvm, u8 __user *usrbuf, u64 len) | |||
1906 | 1907 | ||
1907 | max_irqs = len / sizeof(struct kvm_s390_irq); | 1908 | max_irqs = len / sizeof(struct kvm_s390_irq); |
1908 | 1909 | ||
1910 | if (kvm->arch.gisa && | ||
1911 | kvm_s390_gisa_get_ipm(kvm->arch.gisa)) { | ||
1912 | for (i = 0; i <= MAX_ISC; i++) { | ||
1913 | if (n == max_irqs) { | ||
1914 | /* signal userspace to try again */ | ||
1915 | ret = -ENOMEM; | ||
1916 | goto out_nolock; | ||
1917 | } | ||
1918 | if (kvm_s390_gisa_tac_ipm_gisc(kvm->arch.gisa, i)) { | ||
1919 | irq = (struct kvm_s390_irq *) &buf[n]; | ||
1920 | irq->type = KVM_S390_INT_IO(1, 0, 0, 0); | ||
1921 | irq->u.io.io_int_word = isc_to_int_word(i); | ||
1922 | n++; | ||
1923 | } | ||
1924 | } | ||
1925 | } | ||
1909 | fi = &kvm->arch.float_int; | 1926 | fi = &kvm->arch.float_int; |
1910 | spin_lock(&fi->lock); | 1927 | spin_lock(&fi->lock); |
1911 | for (i = 0; i < FIRQ_LIST_COUNT; i++) { | 1928 | for (i = 0; i < FIRQ_LIST_COUNT; i++) { |
@@ -1944,6 +1961,7 @@ static int get_all_floating_irqs(struct kvm *kvm, u8 __user *usrbuf, u64 len) | |||
1944 | 1961 | ||
1945 | out: | 1962 | out: |
1946 | spin_unlock(&fi->lock); | 1963 | spin_unlock(&fi->lock); |
1964 | out_nolock: | ||
1947 | if (!ret && n > 0) { | 1965 | if (!ret && n > 0) { |
1948 | if (copy_to_user(usrbuf, buf, sizeof(struct kvm_s390_irq) * n)) | 1966 | if (copy_to_user(usrbuf, buf, sizeof(struct kvm_s390_irq) * n)) |
1949 | ret = -EFAULT; | 1967 | ret = -EFAULT; |