On Wed, 16 Apr 2014 13:29:05 +0200 Alexander Graf <ag...@suse.de> wrote:
> > On 14.04.14 18:48, Cornelia Huck wrote: > > 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 <th...@linux.vnet.ibm.com> > > Signed-off-by: Cornelia Huck <cornelia.h...@de.ibm.com> > > --- > > hw/s390x/virtio-ccw.c | 165 > > ++++++++++++++++++++++++++++++++++++++++---- > > hw/s390x/virtio-ccw.h | 2 + > > include/hw/s390x/adapter.h | 23 ++++++ > > include/qemu/typedefs.h | 1 + > > include/sysemu/kvm.h | 2 + > > kvm-all.c | 38 +++++++++- > > kvm-stub.c | 5 ++ > > target-s390x/kvm.c | 5 ++ > > 8 files changed, 228 insertions(+), 13 deletions(-) > > create mode 100644 include/hw/s390x/adapter.h > > > > diff --git a/hw/s390x/virtio-ccw.c b/hw/s390x/virtio-ccw.c > > index 69efa6c..5612ccc 100644 > > --- a/hw/s390x/virtio-ccw.c > > +++ b/hw/s390x/virtio-ccw.c > > @@ -21,6 +21,7 @@ > > #include "hw/sysbus.h" > > #include "qemu/bitops.h" > > #include "hw/virtio/virtio-bus.h" > > +#include "hw/s390x/adapter.h" > > > > #include "ioinst.h" > > #include "css.h" > > @@ -48,7 +49,7 @@ static IndAddr *get_indicator(hwaddr ind_addr, int len) > > return indicator; > > } > > > > -static void release_indicator(IndAddr *indicator) > > +static void release_indicator(uint32_t adapter_id, IndAddr *indicator) > > { > > assert(indicator->refcnt > 0); > > indicator->refcnt--; > > @@ -56,9 +57,31 @@ static void release_indicator(IndAddr *indicator) > > return; > > } > > QTAILQ_REMOVE(&indicator_addresses, indicator, sibling); > > + if (indicator->map) { > > + s390_io_adapter_map(adapter_id, indicator->map, false); > > + } > > g_free(indicator); > > } > > > > +static int map_indicator(uint32_t adapter_id, IndAddr *indicator) > > +{ > > + int ret; > > + > > + if (indicator->map) { > > + return 0; /* already mapped is not an error */ > > + } > > + indicator->map = indicator->addr; > > + ret = s390_io_adapter_map(adapter_id, indicator->map, true); > > + if ((ret != 0) && (ret != -ENOSYS)) { > > + goto out_err; > > + } > > + return 0; > > + > > +out_err: > > + indicator->map = 0; > > + return -EFAULT; > > +} > > + > > static void virtio_ccw_bus_new(VirtioBusState *bus, size_t bus_size, > > VirtioCcwDevice *dev); > > > > @@ -733,7 +756,7 @@ static int virtio_ccw_exit(VirtioCcwDevice *dev) > > g_free(sch); > > } > > if (dev->indicators) { > > - release_indicator(dev->indicators); > > + release_indicator(dev->adapter_id, dev->indicators); > > dev->indicators = NULL; > > } > > return 0; > > @@ -1034,15 +1057,15 @@ static void virtio_ccw_reset(DeviceState *d) > > virtio_reset(vdev); > > css_reset_sch(dev->sch); > > if (dev->indicators) { > > - release_indicator(dev->indicators); > > + release_indicator(dev->adapter_id, dev->indicators); > > dev->indicators = NULL; > > } > > if (dev->indicators2) { > > - release_indicator(dev->indicators2); > > + release_indicator(dev->adapter_id, dev->indicators2); > > dev->indicators2 = NULL; > > } > > if (dev->summary_indicator) { > > - release_indicator(dev->summary_indicator); > > + release_indicator(dev->adapter_id, dev->summary_indicator); > > dev->summary_indicator = NULL; > > } > > } > > @@ -1078,6 +1101,100 @@ static int virtio_ccw_set_host_notifier(DeviceState > > *d, int n, bool assign) > > return virtio_ccw_set_guest2host_notifier(dev, n, assign, false); > > } > > > > +static int virtio_ccw_get_adapter_info(VirtioCcwDevice *dev, > > + AdapterInfo *adapter) > > +{ > > + int r; > > + > > + if (!dev->sch->thinint_active) { > > + return -EINVAL; > > + } > > + > > + r = map_indicator(dev->adapter_id, dev->summary_indicator); > > + if (r) { > > + return r; > > + } > > + r = map_indicator(dev->adapter_id, dev->indicators); > > + if (r) { > > + return r; > > + } > > + adapter->summary_addr = dev->summary_indicator->map; > > + adapter->ind_addr = dev->indicators->map; > > + adapter->ind_offset = dev->ind_bit; > > + adapter->summary_offset = 7; > > + adapter->adapter_id = dev->adapter_id; > > + > > + return 0; > > +} > > + > > +static int virtio_ccw_setup_irqroutes(VirtioCcwDevice *dev, int nvqs) > > +{ > > + int i; > > + VirtIODevice *vdev = virtio_bus_get_device(&dev->bus); > > + int ret; > > + AdapterInfo adapter; > > + > > + ret = virtio_ccw_get_adapter_info(dev, &adapter); > > + if (ret) { > > + return ret; > > + } > > + for (i = 0; i < nvqs; i++) { > > + if (!virtio_queue_get_num(vdev, i)) { > > + break; > > + } > > + ret = kvm_irqchip_add_adapter_route(kvm_state, &adapter); > > Why is interrupt routing code in virtio-ccw.c? Shouldn't that live in > the flic? It needs information about the virtio-ccw device (and the virtio-device). > > > Alex >