mirror of
https://github.com/qemu/qemu.git
synced 2024-11-25 20:03:37 +08:00
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>
This commit is contained in:
parent
6c1dd652a6
commit
1622ffd515
@ -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[] = {
|
||||
|
@ -170,6 +170,23 @@ static int kvm_s390_modify_ais_mode(S390FLICState *fs, uint8_t isc,
|
||||
return ioctl(flic->fd, KVM_SET_DEVICE_ATTR, &attr) ? -errno : 0;
|
||||
}
|
||||
|
||||
static int kvm_s390_inject_airq(S390FLICState *fs, uint8_t type,
|
||||
uint8_t isc, uint8_t flags)
|
||||
{
|
||||
KVMS390FLICState *flic = KVM_S390_FLIC(fs);
|
||||
uint32_t id = css_get_adapter_id(type, isc);
|
||||
struct kvm_device_attr attr = {
|
||||
.group = KVM_DEV_FLIC_AIRQ_INJECT,
|
||||
.attr = id,
|
||||
};
|
||||
|
||||
if (!fs->ais_supported) {
|
||||
return -ENOSYS;
|
||||
}
|
||||
|
||||
return ioctl(flic->fd, KVM_SET_DEVICE_ATTR, &attr) ? -errno : 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* __get_all_irqs - store all pending irqs in buffer
|
||||
* @flic: pointer to flic device state
|
||||
@ -515,6 +532,7 @@ static void kvm_s390_flic_class_init(ObjectClass *oc, void *data)
|
||||
fsc->release_adapter_routes = kvm_s390_release_adapter_routes;
|
||||
fsc->clear_io_irq = kvm_s390_clear_io_flic;
|
||||
fsc->modify_ais_mode = kvm_s390_modify_ais_mode;
|
||||
fsc->inject_airq = kvm_s390_inject_airq;
|
||||
}
|
||||
|
||||
static const TypeInfo kvm_s390_flic_info = {
|
||||
|
@ -73,6 +73,10 @@ flic_create_device(int err) "flic: create device failed %d"
|
||||
flic_no_device_api(int err) "flic: no Device Contral API support %d"
|
||||
flic_reset_failed(int err) "flic: reset failed %d"
|
||||
|
||||
# hw/intc/s390_flic.c
|
||||
qemu_s390_airq_suppressed(uint8_t type, uint8_t isc) "flic: adapter I/O interrupt suppressed (type %x isc %x)"
|
||||
qemu_s390_suppress_airq(uint8_t isc, const char *from, const char *to) "flic: for isc %x, suppress airq by modifying ais mode from %s to %s"
|
||||
|
||||
# hw/intc/aspeed_vic.c
|
||||
aspeed_vic_set_irq(int irq, int level) "Enabling IRQ %d: %d"
|
||||
aspeed_vic_update_fiq(int flags) "Raising FIQ: %d"
|
||||
|
@ -64,6 +64,8 @@ typedef struct S390FLICStateClass {
|
||||
int (*clear_io_irq)(S390FLICState *fs, uint16_t subchannel_id,
|
||||
uint16_t subchannel_nr);
|
||||
int (*modify_ais_mode)(S390FLICState *fs, uint8_t isc, uint16_t mode);
|
||||
int (*inject_airq)(S390FLICState *fs, uint8_t type, uint8_t isc,
|
||||
uint8_t flags);
|
||||
} S390FLICStateClass;
|
||||
|
||||
#define TYPE_KVM_S390_FLIC "s390-flic-kvm"
|
||||
|
Loading…
Reference in New Issue
Block a user