]> Git Repo - qemu.git/blobdiff - hw/intc/s390_flic_kvm.c
hw/intc/arm_gic: modernise the DPRINTF
[qemu.git] / hw / intc / s390_flic_kvm.c
index b471e7a41e46c86148db9f44e810542da500b430..cc44bc4e1e5d9e2d2904e24b28161c69c01c06ef 100644 (file)
@@ -10,6 +10,9 @@
  * directory.
  */
 
+#include "qemu/osdep.h"
+#include "qemu-common.h"
+#include "cpu.h"
 #include <sys/ioctl.h>
 #include "qemu/error-report.h"
 #include "hw/sysbus.h"
@@ -27,6 +30,7 @@ typedef struct KVMS390FLICState {
     S390FLICState parent_obj;
 
     uint32_t fd;
+    bool clear_io_supported;
 } KVMS390FLICState;
 
 DeviceState *s390_flic_kvm_create(void)
@@ -127,6 +131,24 @@ int kvm_s390_inject_flic(struct kvm_s390_irq *irq)
     return flic_enqueue_irqs(irq, sizeof(*irq), flic);
 }
 
+static int kvm_s390_clear_io_flic(S390FLICState *fs, uint16_t subchannel_id,
+                           uint16_t subchannel_nr)
+{
+    KVMS390FLICState *flic = KVM_S390_FLIC(fs);
+    int rc;
+    uint32_t sid = subchannel_id << 16 | subchannel_nr;
+    struct kvm_device_attr attr = {
+        .group = KVM_DEV_FLIC_CLEAR_IO_IRQ,
+        .addr = (uint64_t) &sid,
+        .attr = sizeof(sid),
+    };
+    if (unlikely(!flic->clear_io_supported)) {
+        return -ENOSYS;
+    }
+    rc = ioctl(flic->fd, KVM_SET_DEVICE_ATTR, &attr);
+    return rc ? -errno : 0;
+}
+
 /**
  * __get_all_irqs - store all pending irqs in buffer
  * @flic: pointer to flic device state
@@ -173,21 +195,20 @@ static int kvm_s390_register_io_adapter(S390FLICState *fs, uint32_t id,
         .swap = swap,
     };
     KVMS390FLICState *flic = KVM_S390_FLIC(fs);
-    int r, ret;
+    int r;
     struct kvm_device_attr attr = {
         .group = KVM_DEV_FLIC_ADAPTER_REGISTER,
         .addr = (uint64_t)&adapter,
     };
 
-    if (!kvm_check_extension(kvm_state, KVM_CAP_IRQ_ROUTING)) {
+    if (!kvm_gsi_routing_enabled()) {
         /* nothing to do */
         return 0;
     }
 
     r = ioctl(flic->fd, KVM_SET_DEVICE_ATTR, &attr);
 
-    ret = r ? -errno : 0;
-    return ret;
+    return r ? -errno : 0;
 }
 
 static int kvm_s390_io_adapter_map(S390FLICState *fs, uint32_t id,
@@ -205,7 +226,7 @@ static int kvm_s390_io_adapter_map(S390FLICState *fs, uint32_t id,
     KVMS390FLICState *flic = KVM_S390_FLIC(fs);
     int r;
 
-    if (!kvm_check_extension(kvm_state, KVM_CAP_IRQ_ROUTING)) {
+    if (!kvm_gsi_routing_enabled()) {
         /* nothing to do */
         return 0;
     }
@@ -228,6 +249,8 @@ static int kvm_s390_add_adapter_routes(S390FLICState *fs,
         routes->gsi[i] = ret;
         routes->adapter.ind_offset++;
     }
+    kvm_irqchip_commit_routes(kvm_state);
+
     /* Restore passed-in structure to original state. */
     routes->adapter.ind_offset = ind_offset;
     return 0;
@@ -257,17 +280,20 @@ static void kvm_s390_release_adapter_routes(S390FLICState *fs,
  * kvm_flic_save - Save pending floating interrupts
  * @f: QEMUFile containing migration state
  * @opaque: pointer to flic device state
+ * @size: ignored
  *
  * Note: Pass buf and len to kernel. Start with one page and
  * increase until buffer is sufficient or maxium size is
  * reached
  */
-static void kvm_flic_save(QEMUFile *f, void *opaque)
+static int kvm_flic_save(QEMUFile *f, void *opaque, size_t size,
+                         VMStateField *field, QJSON *vmdesc)
 {
     KVMS390FLICState *flic = opaque;
     int len = FLIC_SAVE_INITIAL_SIZE;
     void *buf;
     int count;
+    int r = 0;
 
     flic_disable_wait_pfault((struct KVMS390FLICState *) opaque);
 
@@ -278,7 +304,7 @@ static void kvm_flic_save(QEMUFile *f, void *opaque)
          * migration state */
         error_report("flic: couldn't allocate memory");
         qemu_put_be64(f, FLIC_FAILED);
-        return;
+        return -ENOMEM;
     }
 
     count = __get_all_irqs(flic, &buf, len);
@@ -289,36 +315,35 @@ static void kvm_flic_save(QEMUFile *f, void *opaque)
          * target system to fail when attempting to load irqs from the
          * migration state */
         qemu_put_be64(f, FLIC_FAILED);
+        r = count;
     } else {
         qemu_put_be64(f, count);
         qemu_put_buffer(f, (uint8_t *) buf,
                         count * sizeof(struct kvm_s390_irq));
     }
     g_free(buf);
+
+    return r;
 }
 
 /**
  * kvm_flic_load - Load pending floating interrupts
  * @f: QEMUFile containing migration state
  * @opaque: pointer to flic device state
- * @version_id: version id for migration
+ * @size: ignored
  *
  * Returns: value of flic_enqueue_irqs, -EINVAL on error
  * Note: Do nothing when no interrupts where stored
  * in QEMUFile
  */
-static int kvm_flic_load(QEMUFile *f, void *opaque, int version_id)
+static int kvm_flic_load(QEMUFile *f, void *opaque, size_t size,
+                         VMStateField *field)
 {
     uint64_t len = 0;
     uint64_t count = 0;
     void *buf = NULL;
     int r = 0;
 
-    if (version_id != FLIC_SAVEVM_VERSION) {
-        r = -EINVAL;
-        goto out;
-    }
-
     flic_enable_pfault((struct KVMS390FLICState *) opaque);
 
     count = qemu_get_be64(f);
@@ -349,10 +374,29 @@ out:
     return r;
 }
 
+static const VMStateDescription kvm_s390_flic_vmstate = {
+    .name = "s390-flic",
+    .version_id = FLIC_SAVEVM_VERSION,
+    .minimum_version_id = FLIC_SAVEVM_VERSION,
+    .fields = (VMStateField[]) {
+        {
+            .name = "irqs",
+            .info = &(const VMStateInfo) {
+                .name = "irqs",
+                .get = kvm_flic_load,
+                .put = kvm_flic_save,
+            },
+            .flags = VMS_SINGLE,
+        },
+        VMSTATE_END_OF_LIST()
+    }
+};
+
 static void kvm_s390_flic_realize(DeviceState *dev, Error **errp)
 {
     KVMS390FLICState *flic_state = KVM_S390_FLIC(dev);
     struct kvm_create_device cd = {0};
+    struct kvm_device_attr test_attr = {0};
     int ret;
 
     flic_state->fd = -1;
@@ -369,16 +413,11 @@ static void kvm_s390_flic_realize(DeviceState *dev, Error **errp)
     }
     flic_state->fd = cd.fd;
 
-    /* Register savevm handler for floating interrupts */
-    register_savevm(NULL, "s390-flic", 0, 1, kvm_flic_save,
-                    kvm_flic_load, (void *) flic_state);
-}
-
-static void kvm_s390_flic_unrealize(DeviceState *dev, Error **errp)
-{
-    KVMS390FLICState *flic_state = KVM_S390_FLIC(dev);
+    /* Check clear_io_irq support */
+    test_attr.group = KVM_DEV_FLIC_CLEAR_IO_IRQ;
+    flic_state->clear_io_supported = !ioctl(flic_state->fd,
+                                            KVM_HAS_DEVICE_ATTR, test_attr);
 
-    unregister_savevm(DEVICE(flic_state), "s390-flic", flic_state);
 }
 
 static void kvm_s390_flic_reset(DeviceState *dev)
@@ -409,12 +448,13 @@ static void kvm_s390_flic_class_init(ObjectClass *oc, void *data)
     S390FLICStateClass *fsc = S390_FLIC_COMMON_CLASS(oc);
 
     dc->realize = kvm_s390_flic_realize;
-    dc->unrealize = kvm_s390_flic_unrealize;
+    dc->vmsd = &kvm_s390_flic_vmstate;
     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;
+    fsc->clear_io_irq = kvm_s390_clear_io_flic;
 }
 
 static const TypeInfo kvm_s390_flic_info = {
This page took 0.029775 seconds and 4 git commands to generate.