aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorMichael Mueller <mimu@linux.vnet.ibm.com>2017-06-14 07:21:32 -0400
committerChristian Borntraeger <borntraeger@de.ibm.com>2018-01-26 05:12:10 -0500
commit24160af6cb289ace9bde980b33d11713c8fc8192 (patch)
tree7207729d4e4a8e0e0abd458e9651698bdfc4220c
parent2496c8e7fe9270bde5e125729c193120e7fa8c67 (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.c18
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
1884static int get_all_floating_irqs(struct kvm *kvm, u8 __user *usrbuf, u64 len) 1885static 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
1945out: 1962out:
1946 spin_unlock(&fi->lock); 1963 spin_unlock(&fi->lock);
1964out_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;