KVM: S390: add new group for flic
authorYi Min Zhao <zyimin@linux.vnet.ibm.com>
Wed, 7 Jun 2017 08:09:52 +0000 (16:09 +0800)
committerChristian Borntraeger <borntraeger@de.ibm.com>
Thu, 22 Jun 2017 10:41:07 +0000 (12:41 +0200)
In some cases, userspace needs to get or set all ais states for example
migration. So we introduce a new group KVM_DEV_FLIC_AISM_ALL to provide
interfaces to get or set the adapter-interruption-suppression mode for
all ISCs. The corresponding documentation is updated.

Signed-off-by: Yi Min Zhao <zyimin@linux.vnet.ibm.com>
Reviewed-by: Halil Pasic <pasic@linux.vnet.ibm.com>
Signed-off-by: Christian Borntraeger <borntraeger@de.ibm.com>
Documentation/virtual/kvm/devices/s390_flic.txt
arch/s390/include/uapi/asm/kvm.h
arch/s390/kvm/interrupt.c

index c2518cea8ab45f13912131295f2506f4475502d6..2f1cbf1301d2291ba23d1073511cb0b2989d61f5 100644 (file)
@@ -16,6 +16,7 @@ FLIC provides support to
 - register and modify adapter interrupt sources (KVM_DEV_FLIC_ADAPTER_*)
 - modify AIS (adapter-interruption-suppression) mode state (KVM_DEV_FLIC_AISM)
 - inject adapter interrupts on a specified adapter (KVM_DEV_FLIC_AIRQ_INJECT)
+- get/set all AIS mode states (KVM_DEV_FLIC_AISM_ALL)
 
 Groups:
   KVM_DEV_FLIC_ENQUEUE
@@ -136,6 +137,20 @@ struct kvm_s390_ais_req {
     an isc according to the adapter-interruption-suppression mode on condition
     that the AIS capability is enabled.
 
+  KVM_DEV_FLIC_AISM_ALL
+    Gets or sets the adapter-interruption-suppression mode for all ISCs. Takes
+    a kvm_s390_ais_all describing:
+
+struct kvm_s390_ais_all {
+       __u8 simm; /* Single-Interruption-Mode mask */
+       __u8 nimm; /* No-Interruption-Mode mask *
+};
+
+    simm contains Single-Interruption-Mode mask for all ISCs, nimm contains
+    No-Interruption-Mode mask for all ISCs. Each bit in simm and nimm corresponds
+    to an ISC (MSB0 bit 0 to ISC 0 and so on). The combination of simm bit and
+    nimm bit presents AIS mode for a ISC.
+
 Note: The KVM_SET_DEVICE_ATTR/KVM_GET_DEVICE_ATTR device ioctls executed on
 FLIC with an unknown group or attribute gives the error code EINVAL (instead of
 ENXIO, as specified in the API documentation). It is not possible to conclude
index d6879a916de525e4cd6183fcd45d3e7703687498..69d09c39bbcd00858121ebf9f6bb1f7a57ff20e1 100644 (file)
@@ -28,6 +28,7 @@
 #define KVM_DEV_FLIC_CLEAR_IO_IRQ      8
 #define KVM_DEV_FLIC_AISM              9
 #define KVM_DEV_FLIC_AIRQ_INJECT       10
+#define KVM_DEV_FLIC_AISM_ALL          11
 /*
  * We can have up to 4*64k pending subchannels + 8 adapter interrupts,
  * as well as up  to ASYNC_PF_PER_VCPU*KVM_MAX_VCPUS pfault done interrupts.
@@ -53,6 +54,11 @@ struct kvm_s390_ais_req {
        __u16 mode;
 };
 
+struct kvm_s390_ais_all {
+       __u8 simm;
+       __u8 nimm;
+};
+
 #define KVM_S390_IO_ADAPTER_MASK 1
 #define KVM_S390_IO_ADAPTER_MAP 2
 #define KVM_S390_IO_ADAPTER_UNMAP 3
index caf15c8a8948e76c1bf7cfb5d5a109df6cee9b3e..72f3aafad5b125ffb862aaf3911abd50b7b6a9fc 100644 (file)
@@ -1876,6 +1876,28 @@ out:
        return ret < 0 ? ret : n;
 }
 
+static int flic_ais_mode_get_all(struct kvm *kvm, struct kvm_device_attr *attr)
+{
+       struct kvm_s390_float_interrupt *fi = &kvm->arch.float_int;
+       struct kvm_s390_ais_all ais;
+
+       if (attr->attr < sizeof(ais))
+               return -EINVAL;
+
+       if (!test_kvm_facility(kvm, 72))
+               return -ENOTSUPP;
+
+       mutex_lock(&fi->ais_lock);
+       ais.simm = fi->simm;
+       ais.nimm = fi->nimm;
+       mutex_unlock(&fi->ais_lock);
+
+       if (copy_to_user((void __user *)attr->addr, &ais, sizeof(ais)))
+               return -EFAULT;
+
+       return 0;
+}
+
 static int flic_get_attr(struct kvm_device *dev, struct kvm_device_attr *attr)
 {
        int r;
@@ -1885,6 +1907,9 @@ static int flic_get_attr(struct kvm_device *dev, struct kvm_device_attr *attr)
                r = get_all_floating_irqs(dev->kvm, (u8 __user *) attr->addr,
                                          attr->attr);
                break;
+       case KVM_DEV_FLIC_AISM_ALL:
+               r = flic_ais_mode_get_all(dev->kvm, attr);
+               break;
        default:
                r = -EINVAL;
        }
@@ -2235,6 +2260,25 @@ static int flic_inject_airq(struct kvm *kvm, struct kvm_device_attr *attr)
        return kvm_s390_inject_airq(kvm, adapter);
 }
 
+static int flic_ais_mode_set_all(struct kvm *kvm, struct kvm_device_attr *attr)
+{
+       struct kvm_s390_float_interrupt *fi = &kvm->arch.float_int;
+       struct kvm_s390_ais_all ais;
+
+       if (!test_kvm_facility(kvm, 72))
+               return -ENOTSUPP;
+
+       if (copy_from_user(&ais, (void __user *)attr->addr, sizeof(ais)))
+               return -EFAULT;
+
+       mutex_lock(&fi->ais_lock);
+       fi->simm = ais.simm;
+       fi->nimm = ais.nimm;
+       mutex_unlock(&fi->ais_lock);
+
+       return 0;
+}
+
 static int flic_set_attr(struct kvm_device *dev, struct kvm_device_attr *attr)
 {
        int r = 0;
@@ -2277,6 +2321,9 @@ static int flic_set_attr(struct kvm_device *dev, struct kvm_device_attr *attr)
        case KVM_DEV_FLIC_AIRQ_INJECT:
                r = flic_inject_airq(dev->kvm, attr);
                break;
+       case KVM_DEV_FLIC_AISM_ALL:
+               r = flic_ais_mode_set_all(dev->kvm, attr);
+               break;
        default:
                r = -EINVAL;
        }
@@ -2298,6 +2345,7 @@ static int flic_has_attr(struct kvm_device *dev,
        case KVM_DEV_FLIC_CLEAR_IO_IRQ:
        case KVM_DEV_FLIC_AISM:
        case KVM_DEV_FLIC_AIRQ_INJECT:
+       case KVM_DEV_FLIC_AISM_ALL:
                return 0;
        }
        return -ENXIO;