diff options
author | Peter Maydell <peter.maydell@linaro.org> | 2015-03-11 15:11:58 +0000 |
---|---|---|
committer | Peter Maydell <peter.maydell@linaro.org> | 2015-03-11 15:11:58 +0000 |
commit | 165fa4091e97bfafbf394acb446623b92998175f (patch) | |
tree | 1d7d3a78c91b1fd58877b02cdcc710967b5b1808 /hw | |
parent | 9159eb9abc31e02797dc55998e71f12c06846d55 (diff) | |
parent | 2d5eeef1c0be68c30ccd60fd7267690d523f702a (diff) |
Merge remote-tracking branch 'remotes/borntraeger/tags/s390x-20150310' into staging
s390x/kvm: Features and fixes for 2.3
- an extension to the elf loader to allow relocations
- make the ccw bios relocatable. This allows for bigger ramdisks
or smaller guests
- Handle all slow SIGPs in QEMU (instead of kernel) for better
compliance and correctness
- tell the KVM module the maximum guest size. This allows KVM
to reduce the number or page table levels
- Several fixes/cleanups
# gpg: Signature made Wed Mar 11 10:17:13 2015 GMT using RSA key ID B5A61C7C
# gpg: Good signature from "Christian Borntraeger (IBM) <borntraeger@de.ibm.com>"
* remotes/borntraeger/tags/s390x-20150310:
s390-ccw: rebuild BIOS
s390/bios: Make the s390-ccw.img relocatable
elf-loader: Provide the possibility to relocate s390 ELF files
s390-ccw.img: Reinitialize guessing on reboot
s390-ccw.img: Allow bigger ramdisk sizes or offsets
s390x/kvm: passing max memory size to accelerator
virtio-ccw: Convert to realize()
virtio-s390: Convert to realize()
virtio-s390: s390_virtio_device_init() can't fail, simplify
s390x/kvm: enable the new SIGP handling in user space
s390x/kvm: deliver SIGP RESTART directly if stopped
s390x: add function to deliver restart irqs
s390x/kvm: SIGP START is only applicable when STOPPED
s390x/kvm: implement handling of new SIGP orders
s390x/kvm: trace all SIGP orders
s390x/kvm: helper to set the SIGP status in SigpInfo
s390x/kvm: pass the SIGP instruction parameter to the SIGP handler
s390x/kvm: more details for SIGP handler with one destination vcpu
s390x: introduce defines for SIGP condition codes
synchronize Linux headers to 4.0-rc3
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
Diffstat (limited to 'hw')
-rw-r--r-- | hw/core/loader.c | 2 | ||||
-rw-r--r-- | hw/s390x/ipl.c | 24 | ||||
-rw-r--r-- | hw/s390x/s390-virtio-bus.c | 97 | ||||
-rw-r--r-- | hw/s390x/s390-virtio-bus.h | 2 | ||||
-rw-r--r-- | hw/s390x/s390-virtio-ccw.c | 10 | ||||
-rw-r--r-- | hw/s390x/virtio-ccw.c | 134 | ||||
-rw-r--r-- | hw/s390x/virtio-ccw.h | 2 |
7 files changed, 164 insertions, 107 deletions
diff --git a/hw/core/loader.c b/hw/core/loader.c index e45dc0b174..76d8acace9 100644 --- a/hw/core/loader.c +++ b/hw/core/loader.c @@ -297,6 +297,7 @@ static void *load_at(int fd, int offset, int size) #undef elf_phdr #undef elf_shdr #undef elf_sym +#undef elf_rela #undef elf_note #undef elf_word #undef elf_sword @@ -307,6 +308,7 @@ static void *load_at(int fd, int offset, int size) #define elf_note elf64_note #define elf_shdr elf64_shdr #define elf_sym elf64_sym +#define elf_rela elf64_rela #define elf_word uint64_t #define elf_sword int64_t #define bswapSZs bswap64s diff --git a/hw/s390x/ipl.c b/hw/s390x/ipl.c index b57adbd99e..d6c0a49071 100644 --- a/hw/s390x/ipl.c +++ b/hw/s390x/ipl.c @@ -14,6 +14,7 @@ #include "sysemu/sysemu.h" #include "cpu.h" #include "elf.h" +#include "exec/ram_addr.h" #include "hw/loader.h" #include "hw/sysbus.h" #include "hw/s390x/virtio-ccw.h" @@ -95,6 +96,16 @@ static const VMStateDescription vmstate_ipl = { } }; +static uint64_t bios_translate_addr(void *opaque, uint64_t srcaddr) +{ + uint64_t dstaddr = *(uint64_t *) opaque; + /* + * Assuming that our s390-ccw.img was linked for starting at address 0, + * we can simply add the destination address for the final location + */ + return srcaddr + dstaddr; +} + static int s390_ipl_init(SysBusDevice *dev) { S390IPLState *ipl = S390_IPL(dev); @@ -109,6 +120,8 @@ static int s390_ipl_init(SysBusDevice *dev) * even if an external kernel has been defined. */ if (!ipl->kernel || ipl->enforce_bios) { + uint64_t fwbase = (MIN(ram_size, 0x80000000U) - 0x200000) & ~0xffffUL; + if (bios_name == NULL) { bios_name = ipl->firmware; } @@ -118,9 +131,14 @@ static int s390_ipl_init(SysBusDevice *dev) hw_error("could not find stage1 bootloader\n"); } - bios_size = load_elf(bios_filename, NULL, NULL, &ipl->bios_start_addr, - NULL, NULL, 1, ELF_MACHINE, 0); - if (bios_size < 0) { + bios_size = load_elf(bios_filename, bios_translate_addr, &fwbase, + &ipl->bios_start_addr, NULL, NULL, 1, + ELF_MACHINE, 0); + if (bios_size > 0) { + /* Adjust ELF start address to final location */ + ipl->bios_start_addr += fwbase; + } else { + /* Try to load non-ELF file (e.g. s390-zipl.rom) */ bios_size = load_image_targphys(bios_filename, ZIPL_IMAGE_START, 4096); ipl->bios_start_addr = ZIPL_IMAGE_START; diff --git a/hw/s390x/s390-virtio-bus.c b/hw/s390x/s390-virtio-bus.c index 39dc2011b9..55a5581d1b 100644 --- a/hw/s390x/s390-virtio-bus.c +++ b/hw/s390x/s390-virtio-bus.c @@ -111,7 +111,8 @@ VirtIOS390Bus *s390_virtio_bus_init(ram_addr_t *ram_size) return bus; } -static int s390_virtio_device_init(VirtIOS390Device *dev, VirtIODevice *vdev) +static void s390_virtio_device_init(VirtIOS390Device *dev, + VirtIODevice *vdev) { VirtIOS390Bus *bus; int dev_len; @@ -135,25 +136,26 @@ static int s390_virtio_device_init(VirtIOS390Device *dev, VirtIODevice *vdev) if (dev->qdev.hotplugged) { s390_virtio_irq(VIRTIO_PARAM_DEV_ADD, dev->dev_offs); } - - return 0; } -static int s390_virtio_net_init(VirtIOS390Device *s390_dev) +static void s390_virtio_net_realize(VirtIOS390Device *s390_dev, Error **errp) { DeviceState *qdev = DEVICE(s390_dev); VirtIONetS390 *dev = VIRTIO_NET_S390(s390_dev); DeviceState *vdev = DEVICE(&dev->vdev); + Error *err = NULL; virtio_net_set_config_size(&dev->vdev, s390_dev->host_features); virtio_net_set_netclient_name(&dev->vdev, qdev->id, object_get_typename(OBJECT(qdev))); qdev_set_parent_bus(vdev, BUS(&s390_dev->bus)); - if (qdev_init(vdev) < 0) { - return -1; + object_property_set_bool(OBJECT(vdev), true, "realized", &err); + if (err) { + error_propagate(errp, err); + return; } - return s390_virtio_device_init(s390_dev, VIRTIO_DEVICE(vdev)); + s390_virtio_device_init(s390_dev, VIRTIO_DEVICE(vdev)); } static void s390_virtio_net_instance_init(Object *obj) @@ -166,15 +168,19 @@ static void s390_virtio_net_instance_init(Object *obj) "bootindex", &error_abort); } -static int s390_virtio_blk_init(VirtIOS390Device *s390_dev) +static void s390_virtio_blk_realize(VirtIOS390Device *s390_dev, Error **errp) { VirtIOBlkS390 *dev = VIRTIO_BLK_S390(s390_dev); DeviceState *vdev = DEVICE(&dev->vdev); + Error *err = NULL; + qdev_set_parent_bus(vdev, BUS(&s390_dev->bus)); - if (qdev_init(vdev) < 0) { - return -1; + object_property_set_bool(OBJECT(vdev), true, "realized", &err); + if (err) { + error_propagate(errp, err); + return; } - return s390_virtio_device_init(s390_dev, VIRTIO_DEVICE(vdev)); + s390_virtio_device_init(s390_dev, VIRTIO_DEVICE(vdev)); } static void s390_virtio_blk_instance_init(Object *obj) @@ -189,13 +195,13 @@ static void s390_virtio_blk_instance_init(Object *obj) "bootindex", &error_abort); } -static int s390_virtio_serial_init(VirtIOS390Device *s390_dev) +static void s390_virtio_serial_realize(VirtIOS390Device *s390_dev, Error **errp) { VirtIOSerialS390 *dev = VIRTIO_SERIAL_S390(s390_dev); DeviceState *vdev = DEVICE(&dev->vdev); DeviceState *qdev = DEVICE(s390_dev); + Error *err = NULL; VirtIOS390Bus *bus; - int r; char *bus_name; bus = DO_UPCAST(VirtIOS390Bus, bus, qdev->parent_bus); @@ -211,16 +217,14 @@ static int s390_virtio_serial_init(VirtIOS390Device *s390_dev) } qdev_set_parent_bus(vdev, BUS(&s390_dev->bus)); - if (qdev_init(vdev) < 0) { - return -1; + object_property_set_bool(OBJECT(vdev), true, "realized", &err); + if (err) { + error_propagate(errp, err); + return; } - r = s390_virtio_device_init(s390_dev, VIRTIO_DEVICE(vdev)); - if (!r) { - bus->console = s390_dev; - } - - return r; + s390_virtio_device_init(s390_dev, VIRTIO_DEVICE(vdev)); + bus->console = s390_dev; } static void s390_virtio_serial_instance_init(Object *obj) @@ -231,11 +235,12 @@ static void s390_virtio_serial_instance_init(Object *obj) TYPE_VIRTIO_SERIAL); } -static int s390_virtio_scsi_init(VirtIOS390Device *s390_dev) +static void s390_virtio_scsi_realize(VirtIOS390Device *s390_dev, Error **errp) { VirtIOSCSIS390 *dev = VIRTIO_SCSI_S390(s390_dev); DeviceState *vdev = DEVICE(&dev->vdev); DeviceState *qdev = DEVICE(s390_dev); + Error *err = NULL; char *bus_name; /* @@ -249,11 +254,13 @@ static int s390_virtio_scsi_init(VirtIOS390Device *s390_dev) } qdev_set_parent_bus(vdev, BUS(&s390_dev->bus)); - if (qdev_init(vdev) < 0) { - return -1; + object_property_set_bool(OBJECT(vdev), true, "realized", &err); + if (err) { + error_propagate(errp, err); + return; } - return s390_virtio_device_init(s390_dev, VIRTIO_DEVICE(vdev)); + s390_virtio_device_init(s390_dev, VIRTIO_DEVICE(vdev)); } static void s390_virtio_scsi_instance_init(Object *obj) @@ -265,17 +272,20 @@ static void s390_virtio_scsi_instance_init(Object *obj) } #ifdef CONFIG_VHOST_SCSI -static int s390_vhost_scsi_init(VirtIOS390Device *s390_dev) +static void s390_vhost_scsi_realize(VirtIOS390Device *s390_dev, Error **errp) { VHostSCSIS390 *dev = VHOST_SCSI_S390(s390_dev); DeviceState *vdev = DEVICE(&dev->vdev); + Error *err = NULL; qdev_set_parent_bus(vdev, BUS(&s390_dev->bus)); - if (qdev_init(vdev) < 0) { - return -1; + object_property_set_bool(OBJECT(vdev), true, "realized", &err); + if (err) { + error_propagate(errp, err); + return; } - return s390_virtio_device_init(s390_dev, VIRTIO_DEVICE(vdev)); + s390_virtio_device_init(s390_dev, VIRTIO_DEVICE(vdev)); } static void s390_vhost_scsi_instance_init(Object *obj) @@ -288,21 +298,24 @@ static void s390_vhost_scsi_instance_init(Object *obj) #endif -static int s390_virtio_rng_init(VirtIOS390Device *s390_dev) +static void s390_virtio_rng_realize(VirtIOS390Device *s390_dev, Error **errp) { VirtIORNGS390 *dev = VIRTIO_RNG_S390(s390_dev); DeviceState *vdev = DEVICE(&dev->vdev); + Error *err = NULL; qdev_set_parent_bus(vdev, BUS(&s390_dev->bus)); - if (qdev_init(vdev) < 0) { - return -1; + object_property_set_bool(OBJECT(vdev), true, "realized", &err); + if (err) { + error_propagate(errp, err); + return; } object_property_set_link(OBJECT(dev), OBJECT(dev->vdev.conf.rng), "rng", NULL); - return s390_virtio_device_init(s390_dev, VIRTIO_DEVICE(vdev)); + s390_virtio_device_init(s390_dev, VIRTIO_DEVICE(vdev)); } static void s390_virtio_rng_instance_init(Object *obj) @@ -509,7 +522,7 @@ static void s390_virtio_net_class_init(ObjectClass *klass, void *data) DeviceClass *dc = DEVICE_CLASS(klass); VirtIOS390DeviceClass *k = VIRTIO_S390_DEVICE_CLASS(klass); - k->init = s390_virtio_net_init; + k->realize = s390_virtio_net_realize; dc->props = s390_virtio_net_properties; } @@ -525,7 +538,7 @@ static void s390_virtio_blk_class_init(ObjectClass *klass, void *data) { VirtIOS390DeviceClass *k = VIRTIO_S390_DEVICE_CLASS(klass); - k->init = s390_virtio_blk_init; + k->realize = s390_virtio_blk_realize; } static const TypeInfo s390_virtio_blk = { @@ -545,7 +558,7 @@ static void s390_virtio_serial_class_init(ObjectClass *klass, void *data) DeviceClass *dc = DEVICE_CLASS(klass); VirtIOS390DeviceClass *k = VIRTIO_S390_DEVICE_CLASS(klass); - k->init = s390_virtio_serial_init; + k->realize = s390_virtio_serial_realize; dc->props = s390_virtio_serial_properties; } @@ -567,7 +580,7 @@ static void s390_virtio_rng_class_init(ObjectClass *klass, void *data) DeviceClass *dc = DEVICE_CLASS(klass); VirtIOS390DeviceClass *k = VIRTIO_S390_DEVICE_CLASS(klass); - k->init = s390_virtio_rng_init; + k->realize = s390_virtio_rng_realize; dc->props = s390_virtio_rng_properties; } @@ -579,14 +592,14 @@ static const TypeInfo s390_virtio_rng = { .class_init = s390_virtio_rng_class_init, }; -static int s390_virtio_busdev_init(DeviceState *dev) +static void s390_virtio_busdev_realize(DeviceState *dev, Error **errp) { VirtIOS390Device *_dev = (VirtIOS390Device *)dev; VirtIOS390DeviceClass *_info = VIRTIO_S390_DEVICE_GET_CLASS(dev); virtio_s390_bus_new(&_dev->bus, sizeof(_dev->bus), _dev); - return _info->init(_dev); + _info->realize(_dev, errp); } static void s390_virtio_busdev_reset(DeviceState *dev) @@ -600,7 +613,7 @@ static void virtio_s390_device_class_init(ObjectClass *klass, void *data) { DeviceClass *dc = DEVICE_CLASS(klass); - dc->init = s390_virtio_busdev_init; + dc->realize = s390_virtio_busdev_realize; dc->bus_type = TYPE_S390_VIRTIO_BUS; dc->reset = s390_virtio_busdev_reset; } @@ -625,7 +638,7 @@ static void s390_virtio_scsi_class_init(ObjectClass *klass, void *data) DeviceClass *dc = DEVICE_CLASS(klass); VirtIOS390DeviceClass *k = VIRTIO_S390_DEVICE_CLASS(klass); - k->init = s390_virtio_scsi_init; + k->realize = s390_virtio_scsi_realize; dc->props = s390_virtio_scsi_properties; } @@ -648,7 +661,7 @@ static void s390_vhost_scsi_class_init(ObjectClass *klass, void *data) DeviceClass *dc = DEVICE_CLASS(klass); VirtIOS390DeviceClass *k = VIRTIO_S390_DEVICE_CLASS(klass); - k->init = s390_vhost_scsi_init; + k->realize = s390_vhost_scsi_realize; dc->props = s390_vhost_scsi_properties; } diff --git a/hw/s390x/s390-virtio-bus.h b/hw/s390x/s390-virtio-bus.h index 92aa9d0499..810a6ef1fc 100644 --- a/hw/s390x/s390-virtio-bus.h +++ b/hw/s390x/s390-virtio-bus.h @@ -83,7 +83,7 @@ typedef struct VirtIOS390Device VirtIOS390Device; typedef struct VirtIOS390DeviceClass { DeviceClass qdev; - int (*init)(VirtIOS390Device *dev); + void (*realize)(VirtIOS390Device *dev, Error **errp); } VirtIOS390DeviceClass; struct VirtIOS390Device { diff --git a/hw/s390x/s390-virtio-ccw.c b/hw/s390x/s390-virtio-ccw.c index 8f0ae59b5f..dac00cec7c 100644 --- a/hw/s390x/s390-virtio-ccw.c +++ b/hw/s390x/s390-virtio-ccw.c @@ -97,6 +97,7 @@ static void ccw_init(MachineState *machine) ram_addr_t pad_size = 0; ram_addr_t maxmem = qemu_opt_get_size(opts, "maxmem", my_ram_size); ram_addr_t standby_mem_size = maxmem - my_ram_size; + uint64_t kvm_limit; /* The storage increment size is a multiple of 1M and is a power of 2. * The number of storage increments must be MAX_STORAGE_INCREMENTS or fewer. @@ -121,6 +122,15 @@ static void ccw_init(MachineState *machine) /* let's propagate the changed ram size into the global variable. */ ram_size = my_ram_size; + machine->maxram_size = my_ram_size + standby_mem_size; + + ret = s390_set_memory_limit(machine->maxram_size, &kvm_limit); + if (ret == -E2BIG) { + hw_error("qemu: host supports a maximum of %" PRIu64 " GB", + kvm_limit >> 30); + } else if (ret) { + hw_error("qemu: setting the guest size failed"); + } /* get a BUS */ css_bus = virtual_css_bus_init(); diff --git a/hw/s390x/virtio-ccw.c b/hw/s390x/virtio-ccw.c index ffbb9c2c89..fce52a929c 100644 --- a/hw/s390x/virtio-ccw.c +++ b/hw/s390x/virtio-ccw.c @@ -607,7 +607,8 @@ static int virtio_ccw_cb(SubchDev *sch, CCW1 ccw) return ret; } -static int virtio_ccw_device_init(VirtioCcwDevice *dev, VirtIODevice *vdev) +static void virtio_ccw_device_realize(VirtioCcwDevice *dev, + VirtIODevice *vdev, Error **errp) { unsigned int cssid = 0; unsigned int ssid = 0; @@ -616,7 +617,6 @@ static int virtio_ccw_device_init(VirtioCcwDevice *dev, VirtIODevice *vdev) bool have_devno = false; bool found = false; SubchDev *sch; - int ret; int num; DeviceState *parent = DEVICE(dev); @@ -639,21 +639,19 @@ static int virtio_ccw_device_init(VirtioCcwDevice *dev, VirtIODevice *vdev) num = sscanf(dev->bus_id, "%x.%x.%04x", &cssid, &ssid, &devno); if (num == 3) { if ((cssid > MAX_CSSID) || (ssid > MAX_SSID)) { - ret = -EINVAL; - error_report("Invalid cssid or ssid: cssid %x, ssid %x", - cssid, ssid); + error_setg(errp, "Invalid cssid or ssid: cssid %x, ssid %x", + cssid, ssid); goto out_err; } /* Enforce use of virtual cssid. */ if (cssid != VIRTUAL_CSSID) { - ret = -EINVAL; - error_report("cssid %x not valid for virtio devices", cssid); + error_setg(errp, "cssid %x not valid for virtio devices", + cssid); goto out_err; } if (css_devno_used(cssid, ssid, devno)) { - ret = -EEXIST; - error_report("Device %x.%x.%04x already exists", cssid, ssid, - devno); + error_setg(errp, "Device %x.%x.%04x already exists", + cssid, ssid, devno); goto out_err; } sch->cssid = cssid; @@ -661,8 +659,7 @@ static int virtio_ccw_device_init(VirtioCcwDevice *dev, VirtIODevice *vdev) sch->devno = devno; have_devno = true; } else { - ret = -EINVAL; - error_report("Malformed devno parameter '%s'", dev->bus_id); + error_setg(errp, "Malformed devno parameter '%s'", dev->bus_id); goto out_err; } } @@ -678,9 +675,8 @@ static int virtio_ccw_device_init(VirtioCcwDevice *dev, VirtIODevice *vdev) } } if (!found) { - ret = -ENODEV; - error_report("No free subchannel found for %x.%x.%04x", cssid, ssid, - devno); + error_setg(errp, "No free subchannel found for %x.%x.%04x", + cssid, ssid, devno); goto out_err; } trace_virtio_ccw_new_device(cssid, ssid, schid, devno, @@ -702,8 +698,7 @@ static int virtio_ccw_device_init(VirtioCcwDevice *dev, VirtIODevice *vdev) if (devno == MAX_SCHID) { devno = 0; } else if (devno == schid - 1) { - ret = -ENODEV; - error_report("No free devno found"); + error_setg(errp, "No free devno found"); goto out_err; } else { devno++; @@ -720,8 +715,7 @@ static int virtio_ccw_device_init(VirtioCcwDevice *dev, VirtIODevice *vdev) } } if (!found) { - ret = -ENODEV; - error_report("Virtual channel subsystem is full!"); + error_setg(errp, "Virtual channel subsystem is full!"); goto out_err; } trace_virtio_ccw_new_device(cssid, ssid, schid, devno, @@ -748,12 +742,11 @@ static int virtio_ccw_device_init(VirtioCcwDevice *dev, VirtIODevice *vdev) css_generate_sch_crws(sch->cssid, sch->ssid, sch->schid, parent->hotplugged, 1); - return 0; + return; out_err: dev->sch = NULL; g_free(sch); - return ret; } static int virtio_ccw_exit(VirtioCcwDevice *dev) @@ -771,21 +764,24 @@ static int virtio_ccw_exit(VirtioCcwDevice *dev) return 0; } -static int virtio_ccw_net_init(VirtioCcwDevice *ccw_dev) +static void virtio_ccw_net_realize(VirtioCcwDevice *ccw_dev, Error **errp) { DeviceState *qdev = DEVICE(ccw_dev); VirtIONetCcw *dev = VIRTIO_NET_CCW(ccw_dev); DeviceState *vdev = DEVICE(&dev->vdev); + Error *err = NULL; virtio_net_set_config_size(&dev->vdev, ccw_dev->host_features[0]); virtio_net_set_netclient_name(&dev->vdev, qdev->id, object_get_typename(OBJECT(qdev))); qdev_set_parent_bus(vdev, BUS(&ccw_dev->bus)); - if (qdev_init(vdev) < 0) { - return -1; + object_property_set_bool(OBJECT(vdev), true, "realized", &err); + if (err) { + error_propagate(errp, err); + return; } - return virtio_ccw_device_init(ccw_dev, VIRTIO_DEVICE(vdev)); + virtio_ccw_device_realize(ccw_dev, VIRTIO_DEVICE(vdev), errp); } static void virtio_ccw_net_instance_init(Object *obj) @@ -798,16 +794,20 @@ static void virtio_ccw_net_instance_init(Object *obj) "bootindex", &error_abort); } -static int virtio_ccw_blk_init(VirtioCcwDevice *ccw_dev) +static void virtio_ccw_blk_realize(VirtioCcwDevice *ccw_dev, Error **errp) { VirtIOBlkCcw *dev = VIRTIO_BLK_CCW(ccw_dev); DeviceState *vdev = DEVICE(&dev->vdev); + Error *err = NULL; + qdev_set_parent_bus(vdev, BUS(&ccw_dev->bus)); - if (qdev_init(vdev) < 0) { - return -1; + object_property_set_bool(OBJECT(vdev), true, "realized", &err); + if (err) { + error_propagate(errp, err); + return; } - return virtio_ccw_device_init(ccw_dev, VIRTIO_DEVICE(vdev)); + virtio_ccw_device_realize(ccw_dev, VIRTIO_DEVICE(vdev), errp); } static void virtio_ccw_blk_instance_init(Object *obj) @@ -822,11 +822,12 @@ static void virtio_ccw_blk_instance_init(Object *obj) "bootindex", &error_abort); } -static int virtio_ccw_serial_init(VirtioCcwDevice *ccw_dev) +static void virtio_ccw_serial_realize(VirtioCcwDevice *ccw_dev, Error **errp) { VirtioSerialCcw *dev = VIRTIO_SERIAL_CCW(ccw_dev); DeviceState *vdev = DEVICE(&dev->vdev); DeviceState *proxy = DEVICE(ccw_dev); + Error *err = NULL; char *bus_name; /* @@ -840,11 +841,13 @@ static int virtio_ccw_serial_init(VirtioCcwDevice *ccw_dev) } qdev_set_parent_bus(vdev, BUS(&ccw_dev->bus)); - if (qdev_init(vdev) < 0) { - return -1; + object_property_set_bool(OBJECT(vdev), true, "realized", &err); + if (err) { + error_propagate(errp, err); + return; } - return virtio_ccw_device_init(ccw_dev, VIRTIO_DEVICE(vdev)); + virtio_ccw_device_realize(ccw_dev, VIRTIO_DEVICE(vdev), errp); } @@ -856,17 +859,20 @@ static void virtio_ccw_serial_instance_init(Object *obj) TYPE_VIRTIO_SERIAL); } -static int virtio_ccw_balloon_init(VirtioCcwDevice *ccw_dev) +static void virtio_ccw_balloon_realize(VirtioCcwDevice *ccw_dev, Error **errp) { VirtIOBalloonCcw *dev = VIRTIO_BALLOON_CCW(ccw_dev); DeviceState *vdev = DEVICE(&dev->vdev); + Error *err = NULL; qdev_set_parent_bus(vdev, BUS(&ccw_dev->bus)); - if (qdev_init(vdev) < 0) { - return -1; + object_property_set_bool(OBJECT(vdev), true, "realized", &err); + if (err) { + error_propagate(errp, err); + return; } - return virtio_ccw_device_init(ccw_dev, VIRTIO_DEVICE(vdev)); + virtio_ccw_device_realize(ccw_dev, VIRTIO_DEVICE(vdev), errp); } static void balloon_ccw_stats_get_all(Object *obj, struct Visitor *v, @@ -909,11 +915,12 @@ static void virtio_ccw_balloon_instance_init(Object *obj) NULL, dev, NULL); } -static int virtio_ccw_scsi_init(VirtioCcwDevice *ccw_dev) +static void virtio_ccw_scsi_realize(VirtioCcwDevice *ccw_dev, Error **errp) { VirtIOSCSICcw *dev = VIRTIO_SCSI_CCW(ccw_dev); DeviceState *vdev = DEVICE(&dev->vdev); DeviceState *qdev = DEVICE(ccw_dev); + Error *err = NULL; char *bus_name; /* @@ -927,11 +934,13 @@ static int virtio_ccw_scsi_init(VirtioCcwDevice *ccw_dev) } qdev_set_parent_bus(vdev, BUS(&ccw_dev->bus)); - if (qdev_init(vdev) < 0) { - return -1; + object_property_set_bool(OBJECT(vdev), true, "realized", &err); + if (err) { + error_propagate(errp, err); + return; } - return virtio_ccw_device_init(ccw_dev, VIRTIO_DEVICE(vdev)); + virtio_ccw_device_realize(ccw_dev, VIRTIO_DEVICE(vdev), errp); } static void virtio_ccw_scsi_instance_init(Object *obj) @@ -945,17 +954,20 @@ static void virtio_ccw_scsi_instance_init(Object *obj) } #ifdef CONFIG_VHOST_SCSI -static int vhost_ccw_scsi_init(VirtioCcwDevice *ccw_dev) +static void vhost_ccw_scsi_realize(VirtioCcwDevice *ccw_dev, Error **errp) { VHostSCSICcw *dev = VHOST_SCSI_CCW(ccw_dev); DeviceState *vdev = DEVICE(&dev->vdev); + Error *err = NULL; qdev_set_parent_bus(vdev, BUS(&ccw_dev->bus)); - if (qdev_init(vdev) < 0) { - return -1; + object_property_set_bool(OBJECT(vdev), true, "realized", &err); + if (err) { + error_propagate(errp, err); + return; } - return virtio_ccw_device_init(ccw_dev, VIRTIO_DEVICE(vdev)); + virtio_ccw_device_realize(ccw_dev, VIRTIO_DEVICE(vdev), errp); } static void vhost_ccw_scsi_instance_init(Object *obj) @@ -967,21 +979,24 @@ static void vhost_ccw_scsi_instance_init(Object *obj) } #endif -static int virtio_ccw_rng_init(VirtioCcwDevice *ccw_dev) +static void virtio_ccw_rng_realize(VirtioCcwDevice *ccw_dev, Error **errp) { VirtIORNGCcw *dev = VIRTIO_RNG_CCW(ccw_dev); DeviceState *vdev = DEVICE(&dev->vdev); + Error *err = NULL; qdev_set_parent_bus(vdev, BUS(&ccw_dev->bus)); - if (qdev_init(vdev) < 0) { - return -1; + object_property_set_bool(OBJECT(vdev), true, "realized", &err); + if (err) { + error_propagate(errp, err); + return; } object_property_set_link(OBJECT(dev), OBJECT(dev->vdev.conf.rng), "rng", NULL); - return virtio_ccw_device_init(ccw_dev, VIRTIO_DEVICE(vdev)); + virtio_ccw_device_realize(ccw_dev, VIRTIO_DEVICE(vdev), errp); } /* DeviceState to VirtioCcwDevice. Note: used on datapath, @@ -1391,7 +1406,7 @@ static void virtio_ccw_net_class_init(ObjectClass *klass, void *data) DeviceClass *dc = DEVICE_CLASS(klass); VirtIOCCWDeviceClass *k = VIRTIO_CCW_DEVICE_CLASS(klass); - k->init = virtio_ccw_net_init; + k->realize = virtio_ccw_net_realize; k->exit = virtio_ccw_exit; dc->reset = virtio_ccw_reset; dc->props = virtio_ccw_net_properties; @@ -1417,7 +1432,7 @@ static void virtio_ccw_blk_class_init(ObjectClass *klass, void *data) DeviceClass *dc = DEVICE_CLASS(klass); VirtIOCCWDeviceClass *k = VIRTIO_CCW_DEVICE_CLASS(klass); - k->init = virtio_ccw_blk_init; + k->realize = virtio_ccw_blk_realize; k->exit = virtio_ccw_exit; dc->reset = virtio_ccw_reset; dc->props = virtio_ccw_blk_properties; @@ -1443,7 +1458,7 @@ static void virtio_ccw_serial_class_init(ObjectClass *klass, void *data) DeviceClass *dc = DEVICE_CLASS(klass); VirtIOCCWDeviceClass *k = VIRTIO_CCW_DEVICE_CLASS(klass); - k->init = virtio_ccw_serial_init; + k->realize = virtio_ccw_serial_realize; k->exit = virtio_ccw_exit; dc->reset = virtio_ccw_reset; dc->props = virtio_ccw_serial_properties; @@ -1469,7 +1484,7 @@ static void virtio_ccw_balloon_class_init(ObjectClass *klass, void *data) DeviceClass *dc = DEVICE_CLASS(klass); VirtIOCCWDeviceClass *k = VIRTIO_CCW_DEVICE_CLASS(klass); - k->init = virtio_ccw_balloon_init; + k->realize = virtio_ccw_balloon_realize; k->exit = virtio_ccw_exit; dc->reset = virtio_ccw_reset; dc->props = virtio_ccw_balloon_properties; @@ -1496,7 +1511,7 @@ static void virtio_ccw_scsi_class_init(ObjectClass *klass, void *data) DeviceClass *dc = DEVICE_CLASS(klass); VirtIOCCWDeviceClass *k = VIRTIO_CCW_DEVICE_CLASS(klass); - k->init = virtio_ccw_scsi_init; + k->realize = virtio_ccw_scsi_realize; k->exit = virtio_ccw_exit; dc->reset = virtio_ccw_reset; dc->props = virtio_ccw_scsi_properties; @@ -1521,7 +1536,7 @@ static void vhost_ccw_scsi_class_init(ObjectClass *klass, void *data) DeviceClass *dc = DEVICE_CLASS(klass); VirtIOCCWDeviceClass *k = VIRTIO_CCW_DEVICE_CLASS(klass); - k->init = vhost_ccw_scsi_init; + k->realize = vhost_ccw_scsi_realize; k->exit = virtio_ccw_exit; dc->reset = virtio_ccw_reset; dc->props = vhost_ccw_scsi_properties; @@ -1558,7 +1573,7 @@ static void virtio_ccw_rng_class_init(ObjectClass *klass, void *data) DeviceClass *dc = DEVICE_CLASS(klass); VirtIOCCWDeviceClass *k = VIRTIO_CCW_DEVICE_CLASS(klass); - k->init = virtio_ccw_rng_init; + k->realize = virtio_ccw_rng_realize; k->exit = virtio_ccw_exit; dc->reset = virtio_ccw_reset; dc->props = virtio_ccw_rng_properties; @@ -1572,14 +1587,13 @@ static const TypeInfo virtio_ccw_rng = { .class_init = virtio_ccw_rng_class_init, }; -static int virtio_ccw_busdev_init(DeviceState *dev) +static void virtio_ccw_busdev_realize(DeviceState *dev, Error **errp) { VirtioCcwDevice *_dev = (VirtioCcwDevice *)dev; VirtIOCCWDeviceClass *_info = VIRTIO_CCW_DEVICE_GET_CLASS(dev); virtio_ccw_bus_new(&_dev->bus, sizeof(_dev->bus), _dev); - - return _info->init(_dev); + _info->realize(_dev, errp); } static int virtio_ccw_busdev_exit(DeviceState *dev) @@ -1622,7 +1636,7 @@ static void virtio_ccw_device_class_init(ObjectClass *klass, void *data) DeviceClass *dc = DEVICE_CLASS(klass); dc->props = virtio_ccw_properties; - dc->init = virtio_ccw_busdev_init; + dc->realize = virtio_ccw_busdev_realize; dc->exit = virtio_ccw_busdev_exit; dc->bus_type = TYPE_VIRTUAL_CSS_BUS; } diff --git a/hw/s390x/virtio-ccw.h b/hw/s390x/virtio-ccw.h index 5a1f16ee5d..4fceda735a 100644 --- a/hw/s390x/virtio-ccw.h +++ b/hw/s390x/virtio-ccw.h @@ -64,7 +64,7 @@ typedef struct VirtioCcwDevice VirtioCcwDevice; typedef struct VirtIOCCWDeviceClass { DeviceClass parent_class; - int (*init)(VirtioCcwDevice *dev); + void (*realize)(VirtioCcwDevice *dev, Error **errp); int (*exit)(VirtioCcwDevice *dev); } VirtIOCCWDeviceClass; |