aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorYi Min Zhao <zyimin@linux.vnet.ibm.com>2017-02-19 21:15:01 -0500
committerChristian Borntraeger <borntraeger@de.ibm.com>2017-04-06 07:15:37 -0400
commita8920950131b1394f9e99ff57a5cf5ceeb0cc25c (patch)
tree1aa07375bfc5eaa1726c0c78f87858a9c75452b6
parent519783935451764b397f2a712de5ea778ff77fdf (diff)
KVM: s390: introduce adapter interrupt inject function
Inject adapter interrupts on a specified adapter which allows to retrieve the adapter flags, e.g. if the adapter is subject to AIS facility or not. And add documentation for this interface. For adapters subject to AIS, handle the airq injection suppression for a given ISC according to the interruption mode: - before injection, if NO-Interruptions Mode, just return 0 and suppress, otherwise, allow the injection. - after injection, if SINGLE-Interruption Mode, change it to NO-Interruptions Mode to suppress the following interrupts. Besides, add tracepoint for suppressed airq and AIS mode transitions. Signed-off-by: Yi Min Zhao <zyimin@linux.vnet.ibm.com> Signed-off-by: Fei Li <sherrylf@linux.vnet.ibm.com> Reviewed-by: Cornelia Huck <cornelia.huck@de.ibm.com> Signed-off-by: Christian Borntraeger <borntraeger@de.ibm.com>
-rw-r--r--Documentation/virtual/kvm/devices/s390_flic.txt9
-rw-r--r--arch/s390/include/uapi/asm/kvm.h1
-rw-r--r--arch/s390/kvm/interrupt.c53
-rw-r--r--arch/s390/kvm/trace-s390.h21
4 files changed, 78 insertions, 6 deletions
diff --git a/Documentation/virtual/kvm/devices/s390_flic.txt b/Documentation/virtual/kvm/devices/s390_flic.txt
index dfd42fd4abd5..c2518cea8ab4 100644
--- a/Documentation/virtual/kvm/devices/s390_flic.txt
+++ b/Documentation/virtual/kvm/devices/s390_flic.txt
@@ -15,6 +15,7 @@ FLIC provides support to
15- enable/disable for the guest transparent async page faults 15- enable/disable for the guest transparent async page faults
16- register and modify adapter interrupt sources (KVM_DEV_FLIC_ADAPTER_*) 16- register and modify adapter interrupt sources (KVM_DEV_FLIC_ADAPTER_*)
17- modify AIS (adapter-interruption-suppression) mode state (KVM_DEV_FLIC_AISM) 17- modify AIS (adapter-interruption-suppression) mode state (KVM_DEV_FLIC_AISM)
18- inject adapter interrupts on a specified adapter (KVM_DEV_FLIC_AIRQ_INJECT)
18 19
19Groups: 20Groups:
20 KVM_DEV_FLIC_ENQUEUE 21 KVM_DEV_FLIC_ENQUEUE
@@ -127,6 +128,14 @@ struct kvm_s390_ais_req {
127 will be suppressed until the mode is set again to ALL-Interruptions 128 will be suppressed until the mode is set again to ALL-Interruptions
128 or SINGLE-Interruption mode. 129 or SINGLE-Interruption mode.
129 130
131 KVM_DEV_FLIC_AIRQ_INJECT
132 Inject adapter interrupts on a specified adapter.
133 attr->attr contains the unique id for the adapter, which allows for
134 adapter-specific checks and actions.
135 For adapters subject to AIS, handle the airq injection suppression for
136 an isc according to the adapter-interruption-suppression mode on condition
137 that the AIS capability is enabled.
138
130Note: The KVM_SET_DEVICE_ATTR/KVM_GET_DEVICE_ATTR device ioctls executed on 139Note: The KVM_SET_DEVICE_ATTR/KVM_GET_DEVICE_ATTR device ioctls executed on
131FLIC with an unknown group or attribute gives the error code EINVAL (instead of 140FLIC with an unknown group or attribute gives the error code EINVAL (instead of
132ENXIO, as specified in the API documentation). It is not possible to conclude 141ENXIO, as specified in the API documentation). It is not possible to conclude
diff --git a/arch/s390/include/uapi/asm/kvm.h b/arch/s390/include/uapi/asm/kvm.h
index 50d2a927c990..2c9ad251fa33 100644
--- a/arch/s390/include/uapi/asm/kvm.h
+++ b/arch/s390/include/uapi/asm/kvm.h
@@ -27,6 +27,7 @@
27#define KVM_DEV_FLIC_ADAPTER_MODIFY 7 27#define KVM_DEV_FLIC_ADAPTER_MODIFY 7
28#define KVM_DEV_FLIC_CLEAR_IO_IRQ 8 28#define KVM_DEV_FLIC_CLEAR_IO_IRQ 8
29#define KVM_DEV_FLIC_AISM 9 29#define KVM_DEV_FLIC_AISM 9
30#define KVM_DEV_FLIC_AIRQ_INJECT 10
30/* 31/*
31 * We can have up to 4*64k pending subchannels + 8 adapter interrupts, 32 * We can have up to 4*64k pending subchannels + 8 adapter interrupts,
32 * as well as up to ASYNC_PF_PER_VCPU*KVM_MAX_VCPUS pfault done interrupts. 33 * as well as up to ASYNC_PF_PER_VCPU*KVM_MAX_VCPUS pfault done interrupts.
diff --git a/arch/s390/kvm/interrupt.c b/arch/s390/kvm/interrupt.c
index 96b689e48c08..482673e3436d 100644
--- a/arch/s390/kvm/interrupt.c
+++ b/arch/s390/kvm/interrupt.c
@@ -2191,6 +2191,48 @@ static int modify_ais_mode(struct kvm *kvm, struct kvm_device_attr *attr)
2191 return ret; 2191 return ret;
2192} 2192}
2193 2193
2194static int kvm_s390_inject_airq(struct kvm *kvm,
2195 struct s390_io_adapter *adapter)
2196{
2197 struct kvm_s390_float_interrupt *fi = &kvm->arch.float_int;
2198 struct kvm_s390_interrupt s390int = {
2199 .type = KVM_S390_INT_IO(1, 0, 0, 0),
2200 .parm = 0,
2201 .parm64 = (adapter->isc << 27) | 0x80000000,
2202 };
2203 int ret = 0;
2204
2205 if (!fi->ais_enabled || !adapter->suppressible)
2206 return kvm_s390_inject_vm(kvm, &s390int);
2207
2208 mutex_lock(&fi->ais_lock);
2209 if (fi->nimm & AIS_MODE_MASK(adapter->isc)) {
2210 trace_kvm_s390_airq_suppressed(adapter->id, adapter->isc);
2211 goto out;
2212 }
2213
2214 ret = kvm_s390_inject_vm(kvm, &s390int);
2215 if (!ret && (fi->simm & AIS_MODE_MASK(adapter->isc))) {
2216 fi->nimm |= AIS_MODE_MASK(adapter->isc);
2217 trace_kvm_s390_modify_ais_mode(adapter->isc,
2218 KVM_S390_AIS_MODE_SINGLE, 2);
2219 }
2220out:
2221 mutex_unlock(&fi->ais_lock);
2222 return ret;
2223}
2224
2225static int flic_inject_airq(struct kvm *kvm, struct kvm_device_attr *attr)
2226{
2227 unsigned int id = attr->attr;
2228 struct s390_io_adapter *adapter = get_io_adapter(kvm, id);
2229
2230 if (!adapter)
2231 return -EINVAL;
2232
2233 return kvm_s390_inject_airq(kvm, adapter);
2234}
2235
2194static int flic_set_attr(struct kvm_device *dev, struct kvm_device_attr *attr) 2236static int flic_set_attr(struct kvm_device *dev, struct kvm_device_attr *attr)
2195{ 2237{
2196 int r = 0; 2238 int r = 0;
@@ -2230,6 +2272,9 @@ static int flic_set_attr(struct kvm_device *dev, struct kvm_device_attr *attr)
2230 case KVM_DEV_FLIC_AISM: 2272 case KVM_DEV_FLIC_AISM:
2231 r = modify_ais_mode(dev->kvm, attr); 2273 r = modify_ais_mode(dev->kvm, attr);
2232 break; 2274 break;
2275 case KVM_DEV_FLIC_AIRQ_INJECT:
2276 r = flic_inject_airq(dev->kvm, attr);
2277 break;
2233 default: 2278 default:
2234 r = -EINVAL; 2279 r = -EINVAL;
2235 } 2280 }
@@ -2250,6 +2295,7 @@ static int flic_has_attr(struct kvm_device *dev,
2250 case KVM_DEV_FLIC_ADAPTER_MODIFY: 2295 case KVM_DEV_FLIC_ADAPTER_MODIFY:
2251 case KVM_DEV_FLIC_CLEAR_IO_IRQ: 2296 case KVM_DEV_FLIC_CLEAR_IO_IRQ:
2252 case KVM_DEV_FLIC_AISM: 2297 case KVM_DEV_FLIC_AISM:
2298 case KVM_DEV_FLIC_AIRQ_INJECT:
2253 return 0; 2299 return 0;
2254 } 2300 }
2255 return -ENXIO; 2301 return -ENXIO;
@@ -2360,12 +2406,7 @@ static int set_adapter_int(struct kvm_kernel_irq_routing_entry *e,
2360 ret = adapter_indicators_set(kvm, adapter, &e->adapter); 2406 ret = adapter_indicators_set(kvm, adapter, &e->adapter);
2361 up_read(&adapter->maps_lock); 2407 up_read(&adapter->maps_lock);
2362 if ((ret > 0) && !adapter->masked) { 2408 if ((ret > 0) && !adapter->masked) {
2363 struct kvm_s390_interrupt s390int = { 2409 ret = kvm_s390_inject_airq(kvm, adapter);
2364 .type = KVM_S390_INT_IO(1, 0, 0, 0),
2365 .parm = 0,
2366 .parm64 = (adapter->isc << 27) | 0x80000000,
2367 };
2368 ret = kvm_s390_inject_vm(kvm, &s390int);
2369 if (ret == 0) 2410 if (ret == 0)
2370 ret = 1; 2411 ret = 1;
2371 } 2412 }
diff --git a/arch/s390/kvm/trace-s390.h b/arch/s390/kvm/trace-s390.h
index b32994d1546a..78b7e847984a 100644
--- a/arch/s390/kvm/trace-s390.h
+++ b/arch/s390/kvm/trace-s390.h
@@ -311,6 +311,27 @@ TRACE_EVENT(kvm_s390_modify_ais_mode,
311 "Single-Interruption Mode" : "No-Interruptions Mode") 311 "Single-Interruption Mode" : "No-Interruptions Mode")
312 ); 312 );
313 313
314/*
315 * Trace point for suppressed adapter I/O interrupt.
316 */
317TRACE_EVENT(kvm_s390_airq_suppressed,
318 TP_PROTO(__u32 id, __u8 isc),
319 TP_ARGS(id, isc),
320
321 TP_STRUCT__entry(
322 __field(__u32, id)
323 __field(__u8, isc)
324 ),
325
326 TP_fast_assign(
327 __entry->id = id;
328 __entry->isc = isc;
329 ),
330
331 TP_printk("adapter I/O interrupt suppressed (id:%x isc:%x)",
332 __entry->id, __entry->isc)
333 );
334
314 335
315#endif /* _TRACE_KVMS390_H */ 336#endif /* _TRACE_KVMS390_H */
316 337