diff options
author | Yi Min Zhao <zyimin@linux.vnet.ibm.com> | 2017-02-17 15:00:59 +0800 |
---|---|---|
committer | Christian Borntraeger <borntraeger@de.ibm.com> | 2017-07-14 12:29:47 +0200 |
commit | 1622ffd5151ad09c47785a380531ef1ebfc95be8 (patch) | |
tree | 03ec6c19ce9e9d272a4785acf44b811e7bed4d01 /hw/intc/s390_flic.c | |
parent | 6c1dd652a606f4446cdb8883ac68d6fb54b02e5c (diff) |
s390x/flic: introduce inject_airq callback
Let's introduce a specialized way to inject adapter interrupts that,
unlike the common interrupt injection method, allows to take the
characteristics of the adapter into account.
For adapters subject to AIS facility:
- for non-kvm case, we handle the suppression for a given ISC in QEMU.
- for kvm case, we pass adapter id to kvm to do airq injection.
Add add tracepoint for suppressed airq and suppressing airq.
Signed-off-by: Yi Min Zhao <zyimin@linux.vnet.ibm.com>
Signed-off-by: Fei Li <sherrylf@linux.vnet.ibm.com>
Signed-off-by: Christian Borntraeger <borntraeger@de.ibm.com>
Diffstat (limited to 'hw/intc/s390_flic.c')
-rw-r--r-- | hw/intc/s390_flic.c | 27 |
1 files changed, 27 insertions, 0 deletions
diff --git a/hw/intc/s390_flic.c b/hw/intc/s390_flic.c index ce7f355248..efcb1dd0f1 100644 --- a/hw/intc/s390_flic.c +++ b/hw/intc/s390_flic.c @@ -13,8 +13,11 @@ #include "qemu/osdep.h" #include "qemu/error-report.h" #include "hw/sysbus.h" +#include "hw/s390x/ioinst.h" #include "hw/s390x/s390_flic.h" +#include "hw/s390x/css.h" #include "trace.h" +#include "cpu.h" #include "hw/qdev.h" #include "qapi/error.h" #include "hw/s390x/s390-virtio-ccw.h" @@ -100,6 +103,29 @@ static int qemu_s390_modify_ais_mode(S390FLICState *fs, uint8_t isc, return 0; } +static int qemu_s390_inject_airq(S390FLICState *fs, uint8_t type, + uint8_t isc, uint8_t flags) +{ + QEMUS390FLICState *flic = QEMU_S390_FLIC(fs); + bool flag = flags & S390_ADAPTER_SUPPRESSIBLE; + uint32_t io_int_word = (isc << 27) | IO_INT_WORD_AI; + + if (flag && (flic->nimm & AIS_MODE_MASK(isc))) { + trace_qemu_s390_airq_suppressed(type, isc); + return 0; + } + + s390_io_interrupt(0, 0, 0, io_int_word); + + if (flag && (flic->simm & AIS_MODE_MASK(isc))) { + flic->nimm |= AIS_MODE_MASK(isc); + trace_qemu_s390_suppress_airq(isc, "Single-Interruption Mode", + "NO-Interruptions Mode"); + } + + return 0; +} + static void qemu_s390_flic_reset(DeviceState *dev) { QEMUS390FLICState *flic = QEMU_S390_FLIC(dev); @@ -120,6 +146,7 @@ static void qemu_s390_flic_class_init(ObjectClass *oc, void *data) fsc->release_adapter_routes = qemu_s390_release_adapter_routes; fsc->clear_io_irq = qemu_s390_clear_io_flic; fsc->modify_ais_mode = qemu_s390_modify_ais_mode; + fsc->inject_airq = qemu_s390_inject_airq; } static Property s390_flic_common_properties[] = { |