diff options
author | Cornelia Huck <cornelia.huck@de.ibm.com> | 2013-07-15 17:45:03 +0200 |
---|---|---|
committer | Cornelia Huck <cornelia.huck@de.ibm.com> | 2014-05-20 13:05:58 +0200 |
commit | d426d9fba8ea5d728038a9bea6a7c51f11941157 (patch) | |
tree | 447cd6550e5d99703763c96e12c83f699c71275f /hw/intc | |
parent | 7bca3892cb951afb5945480b090e3fb93578cd6a (diff) | |
download | qemu-d426d9fba8ea5d728038a9bea6a7c51f11941157.zip qemu-d426d9fba8ea5d728038a9bea6a7c51f11941157.tar.gz qemu-d426d9fba8ea5d728038a9bea6a7c51f11941157.tar.bz2 |
s390x/virtio-ccw: wire up irq routing and irqfds
Make use of the new s390 adapter irq routing support to enable real
in-kernel irqfds for virtio-ccw with adapter interrupts.
Note that s390 doesn't provide the common KVM_CAP_IRQCHIP capability, but
rather needs KVM_CAP_S390_IRQCHIP to be enabled. This is to ensure backward
compatibility.
Reviewed-by: Thomas Huth <thuth@linux.vnet.ibm.com>
Reviewed-by: Christian Borntraeger <borntraeger@de.ibm.com>
Acked-by: Paolo Bonzini <pbonzini@redhat.com>
Signed-off-by: Cornelia Huck <cornelia.huck@de.ibm.com>
Diffstat (limited to 'hw/intc')
-rw-r--r-- | hw/intc/s390_flic.c | 21 | ||||
-rw-r--r-- | hw/intc/s390_flic_kvm.c | 66 |
2 files changed, 87 insertions, 0 deletions
diff --git a/hw/intc/s390_flic.c b/hw/intc/s390_flic.c index 2b56835..03c5e89 100644 --- a/hw/intc/s390_flic.c +++ b/hw/intc/s390_flic.c @@ -52,11 +52,32 @@ static int qemu_s390_register_io_adapter(S390FLICState *fs, uint32_t id, return 0; } +static int qemu_s390_io_adapter_map(S390FLICState *fs, uint32_t id, + uint64_t map_addr, bool do_map) +{ + /* nothing to do */ + return 0; +} + +static int qemu_s390_add_adapter_routes(S390FLICState *fs, + AdapterRoutes *routes) +{ + return -ENOSYS; +} + +static void qemu_s390_release_adapter_routes(S390FLICState *fs, + AdapterRoutes *routes) +{ +} + static void qemu_s390_flic_class_init(ObjectClass *oc, void *data) { S390FLICStateClass *fsc = S390_FLIC_COMMON_CLASS(oc); fsc->register_io_adapter = qemu_s390_register_io_adapter; + fsc->io_adapter_map = qemu_s390_io_adapter_map; + fsc->add_adapter_routes = qemu_s390_add_adapter_routes; + fsc->release_adapter_routes = qemu_s390_release_adapter_routes; } static const TypeInfo qemu_s390_flic_info = { diff --git a/hw/intc/s390_flic_kvm.c b/hw/intc/s390_flic_kvm.c index cc4072e..46c9e61 100644 --- a/hw/intc/s390_flic_kvm.c +++ b/hw/intc/s390_flic_kvm.c @@ -16,6 +16,7 @@ #include "sysemu/kvm.h" #include "migration/qemu-file.h" #include "hw/s390x/s390_flic.h" +#include "hw/s390x/adapter.h" #include "trace.h" #define FLIC_SAVE_INITIAL_SIZE getpagesize() @@ -178,6 +179,68 @@ static int kvm_s390_register_io_adapter(S390FLICState *fs, uint32_t id, return ret; } +static int kvm_s390_io_adapter_map(S390FLICState *fs, uint32_t id, + uint64_t map_addr, bool do_map) +{ + struct kvm_s390_io_adapter_req req = { + .id = id, + .type = do_map ? KVM_S390_IO_ADAPTER_MAP : KVM_S390_IO_ADAPTER_UNMAP, + .addr = map_addr, + }; + struct kvm_device_attr attr = { + .group = KVM_DEV_FLIC_ADAPTER_MODIFY, + .addr = (uint64_t)&req, + }; + KVMS390FLICState *flic = KVM_S390_FLIC(fs); + int r; + + if (!kvm_check_extension(kvm_state, KVM_CAP_IRQ_ROUTING)) { + return -ENOSYS; + } + + r = ioctl(flic->fd, KVM_SET_DEVICE_ATTR, &attr); + return r ? -errno : 0; +} + +static int kvm_s390_add_adapter_routes(S390FLICState *fs, + AdapterRoutes *routes) +{ + int ret, i; + uint64_t ind_offset = routes->adapter.ind_offset; + + for (i = 0; i < routes->num_routes; i++) { + ret = kvm_irqchip_add_adapter_route(kvm_state, &routes->adapter); + if (ret < 0) { + goto out_undo; + } + routes->gsi[i] = ret; + routes->adapter.ind_offset++; + } + /* Restore passed-in structure to original state. */ + routes->adapter.ind_offset = ind_offset; + return 0; +out_undo: + while (--i >= 0) { + kvm_irqchip_release_virq(kvm_state, routes->gsi[i]); + routes->gsi[i] = -1; + } + routes->adapter.ind_offset = ind_offset; + return ret; +} + +static void kvm_s390_release_adapter_routes(S390FLICState *fs, + AdapterRoutes *routes) +{ + int i; + + for (i = 0; i < routes->num_routes; i++) { + if (routes->gsi[i] >= 0) { + kvm_irqchip_release_virq(kvm_state, routes->gsi[i]); + routes->gsi[i] = -1; + } + } +} + /** * kvm_flic_save - Save pending floating interrupts * @f: QEMUFile containing migration state @@ -337,6 +400,9 @@ static void kvm_s390_flic_class_init(ObjectClass *oc, void *data) dc->unrealize = kvm_s390_flic_unrealize; dc->reset = kvm_s390_flic_reset; fsc->register_io_adapter = kvm_s390_register_io_adapter; + fsc->io_adapter_map = kvm_s390_io_adapter_map; + fsc->add_adapter_routes = kvm_s390_add_adapter_routes; + fsc->release_adapter_routes = kvm_s390_release_adapter_routes; } static const TypeInfo kvm_s390_flic_info = { |