aboutsummaryrefslogtreecommitdiff
path: root/hw
diff options
context:
space:
mode:
authorPeter Maydell <peter.maydell@linaro.org>2015-03-11 15:11:58 +0000
committerPeter Maydell <peter.maydell@linaro.org>2015-03-11 15:11:58 +0000
commit165fa4091e97bfafbf394acb446623b92998175f (patch)
tree1d7d3a78c91b1fd58877b02cdcc710967b5b1808 /hw
parent9159eb9abc31e02797dc55998e71f12c06846d55 (diff)
parent2d5eeef1c0be68c30ccd60fd7267690d523f702a (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.c2
-rw-r--r--hw/s390x/ipl.c24
-rw-r--r--hw/s390x/s390-virtio-bus.c97
-rw-r--r--hw/s390x/s390-virtio-bus.h2
-rw-r--r--hw/s390x/s390-virtio-ccw.c10
-rw-r--r--hw/s390x/virtio-ccw.c134
-rw-r--r--hw/s390x/virtio-ccw.h2
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;