Skip to content

Commit

Permalink
Merge remote-tracking branch 'remotes/cohuck/tags/s390x-20170224' int…
Browse files Browse the repository at this point in the history
…o staging

A selection of s390x patches:
- cleanups, fixes and improvements
- program check loop detection (useful with the corresponding kernel
  patch)
- wire up virtio-crypto for ccw
- and finally support many virtqueues for virtio-ccw

# gpg: Signature made Fri 24 Feb 2017 09:19:19 GMT
# gpg:                using RSA key 0xDECF6B93C6F02FAF
# gpg: Good signature from "Cornelia Huck <huckc@linux.vnet.ibm.com>"
# gpg:                 aka "Cornelia Huck <cornelia.huck@de.ibm.com>"
# Primary key fingerprint: C3D0 D66D C362 4FF6 A8C0  18CE DECF 6B93 C6F0 2FAF

* remotes/cohuck/tags/s390x-20170224:
  s390x/css: handle format-0 TIC CCW correctly
  s390x/arch_dump: pass cpuid into notes sections
  s390x/arch_dump: use proper note name and note size
  virtio-ccw: support VIRTIO_QUEUE_MAX virtqueues
  s390x: bump ADAPTER_ROUTES_MAX_GSI
  virtio-ccw: check flic->adapter_routes_max_batch
  s390x: add property adapter_routes_max_batch
  virtio-ccw: Check the number of vqs in CCW_CMD_SET_IND
  virtio-ccw: add virtio-crypto-ccw device
  virtio-ccw: handle virtio 1 only devices
  s390x/flic: fail migration on source already
  s390x/kvm: detect some program check loops
  s390x/s390-virtio: get rid of DPRINTF

Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
  • Loading branch information
pm215 committed Feb 25, 2017
2 parents f62ab6b + 9f94f84 commit 2421f38
Show file tree
Hide file tree
Showing 10 changed files with 250 additions and 60 deletions.
28 changes: 28 additions & 0 deletions hw/intc/s390_flic.c
Expand Up @@ -16,6 +16,8 @@
#include "migration/qemu-file.h"
#include "hw/s390x/s390_flic.h"
#include "trace.h"
#include "hw/qdev.h"
#include "qapi/error.h"

S390FLICState *s390_get_flic(void)
{
Expand Down Expand Up @@ -85,17 +87,43 @@ static void qemu_s390_flic_class_init(ObjectClass *oc, void *data)
fsc->clear_io_irq = qemu_s390_clear_io_flic;
}

static Property s390_flic_common_properties[] = {
DEFINE_PROP_UINT32("adapter_routes_max_batch", S390FLICState,
adapter_routes_max_batch, ADAPTER_ROUTES_MAX_GSI),
DEFINE_PROP_END_OF_LIST(),
};

static void s390_flic_common_realize(DeviceState *dev, Error **errp)
{
uint32_t max_batch = S390_FLIC_COMMON(dev)->adapter_routes_max_batch;

if (max_batch > ADAPTER_ROUTES_MAX_GSI) {
error_setg(errp, "flic adapter_routes_max_batch too big"
"%d (%d allowed)", max_batch, ADAPTER_ROUTES_MAX_GSI);
}
}

static void s390_flic_class_init(ObjectClass *oc, void *data)
{
DeviceClass *dc = DEVICE_CLASS(oc);

dc->props = s390_flic_common_properties;
dc->realize = s390_flic_common_realize;
}

static const TypeInfo qemu_s390_flic_info = {
.name = TYPE_QEMU_S390_FLIC,
.parent = TYPE_S390_FLIC_COMMON,
.instance_size = sizeof(QEMUS390FLICState),
.class_init = qemu_s390_flic_class_init,
};


static const TypeInfo s390_flic_common_info = {
.name = TYPE_S390_FLIC_COMMON,
.parent = TYPE_SYS_BUS_DEVICE,
.instance_size = sizeof(S390FLICState),
.class_init = s390_flic_class_init,
.class_size = sizeof(S390FLICStateClass),
};

Expand Down
6 changes: 4 additions & 2 deletions hw/intc/s390_flic_kvm.c
Expand Up @@ -293,6 +293,7 @@ static int kvm_flic_save(QEMUFile *f, void *opaque, size_t size,
int len = FLIC_SAVE_INITIAL_SIZE;
void *buf;
int count;
int r = 0;

flic_disable_wait_pfault((struct KVMS390FLICState *) opaque);

Expand All @@ -303,7 +304,7 @@ static int kvm_flic_save(QEMUFile *f, void *opaque, size_t size,
* migration state */
error_report("flic: couldn't allocate memory");
qemu_put_be64(f, FLIC_FAILED);
return 0;
return -ENOMEM;
}

count = __get_all_irqs(flic, &buf, len);
Expand All @@ -314,14 +315,15 @@ static int kvm_flic_save(QEMUFile *f, void *opaque, size_t size,
* 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 0;
return r;
}

/**
Expand Down
15 changes: 9 additions & 6 deletions hw/s390x/css.c
Expand Up @@ -368,13 +368,16 @@ static CCW1 copy_ccw_from_guest(hwaddr addr, bool fmt1)
ret.cda = be32_to_cpu(tmp1.cda);
} else {
cpu_physical_memory_read(addr, &tmp0, sizeof(tmp0));
ret.cmd_code = tmp0.cmd_code;
ret.flags = tmp0.flags;
ret.count = be16_to_cpu(tmp0.count);
ret.cda = be16_to_cpu(tmp0.cda1) | (tmp0.cda0 << 16);
if ((ret.cmd_code & 0x0f) == CCW_CMD_TIC) {
ret.cmd_code &= 0x0f;
if ((tmp0.cmd_code & 0x0f) == CCW_CMD_TIC) {
ret.cmd_code = CCW_CMD_TIC;
ret.flags = 0;
ret.count = 0;
} else {
ret.cmd_code = tmp0.cmd_code;
ret.flags = tmp0.flags;
ret.count = be16_to_cpu(tmp0.count);
}
ret.cda = be16_to_cpu(tmp0.cda1) | (tmp0.cda0 << 16);
}
return ret;
}
Expand Down
9 changes: 7 additions & 2 deletions hw/s390x/s390-virtio-ccw.c
Expand Up @@ -63,7 +63,7 @@ static int virtio_ccw_hcall_notify(const uint64_t *args)
if (!sch || !css_subch_visible(sch)) {
return -EINVAL;
}
if (queue >= VIRTIO_CCW_QUEUE_MAX) {
if (queue >= VIRTIO_QUEUE_MAX) {
return -EINVAL;
}
virtio_queue_notify(virtio_ccw_get_vdev(sch), queue);
Expand Down Expand Up @@ -336,7 +336,12 @@ static const TypeInfo ccw_machine_info = {
type_init(ccw_machine_register_##suffix)

#define CCW_COMPAT_2_8 \
HW_COMPAT_2_8
HW_COMPAT_2_8 \
{\
.driver = TYPE_S390_FLIC_COMMON,\
.property = "adapter_routes_max_batch",\
.value = "64",\
},

#define CCW_COMPAT_2_7 \
HW_COMPAT_2_7
Expand Down
10 changes: 0 additions & 10 deletions hw/s390x/s390-virtio.c
Expand Up @@ -44,16 +44,6 @@
#include "hw/s390x/ipl.h"
#include "cpu.h"

//#define DEBUG_S390

#ifdef DEBUG_S390
#define DPRINTF(fmt, ...) \
do { fprintf(stderr, fmt, ## __VA_ARGS__); } while (0)
#else
#define DPRINTF(fmt, ...) \
do { } while (0)
#endif

#define MAX_BLK_DEVS 10

#define S390_TOD_CLOCK_VALUE_MISSING 0x00
Expand Down
109 changes: 100 additions & 9 deletions hw/s390x/virtio-ccw.c
Expand Up @@ -35,6 +35,8 @@
#include "trace.h"
#include "hw/s390x/css-bridge.h"

#define NR_CLASSIC_INDICATOR_BITS 64

static void virtio_ccw_bus_new(VirtioBusState *bus, size_t bus_size,
VirtioCcwDevice *dev);

Expand Down Expand Up @@ -126,7 +128,7 @@ static int virtio_ccw_set_vqs(SubchDev *sch, VqInfoBlock *info,
uint16_t num = info ? info->num : linfo->num;
uint64_t desc = info ? info->desc : linfo->queue;

if (index >= VIRTIO_CCW_QUEUE_MAX) {
if (index >= VIRTIO_QUEUE_MAX) {
return -EINVAL;
}

Expand Down Expand Up @@ -162,7 +164,7 @@ static int virtio_ccw_set_vqs(SubchDev *sch, VqInfoBlock *info,
virtio_queue_set_vector(vdev, index, index);
}
/* tell notify handler in case of config change */
vdev->config_vector = VIRTIO_CCW_QUEUE_MAX;
vdev->config_vector = VIRTIO_QUEUE_MAX;
return 0;
}

Expand Down Expand Up @@ -280,6 +282,15 @@ static int virtio_ccw_cb(SubchDev *sch, CCW1 ccw)
ccw.cmd_code);
check_len = !((ccw.flags & CCW_FLAG_SLI) && !(ccw.flags & CCW_FLAG_DC));

if (dev->force_revision_1 && dev->revision < 0 &&
ccw.cmd_code != CCW_CMD_SET_VIRTIO_REV) {
/*
* virtio-1 drivers must start with negotiating to a revision >= 1,
* so post a command reject for all other commands
*/
return -ENOSYS;
}

/* Look at the command. */
switch (ccw.cmd_code) {
case CCW_CMD_SET_VQ:
Expand Down Expand Up @@ -500,6 +511,11 @@ static int virtio_ccw_cb(SubchDev *sch, CCW1 ccw)
ret = -ENOSYS;
break;
}
if (virtio_get_num_queues(vdev) > NR_CLASSIC_INDICATOR_BITS) {
/* More queues than indicator bits --> trigger a reject */
ret = -ENOSYS;
break;
}
if (!ccw.cda) {
ret = -EFAULT;
} else {
Expand Down Expand Up @@ -549,7 +565,7 @@ static int virtio_ccw_cb(SubchDev *sch, CCW1 ccw)
ccw.cda,
MEMTXATTRS_UNSPECIFIED,
NULL);
if (vq_config.index >= VIRTIO_CCW_QUEUE_MAX) {
if (vq_config.index >= VIRTIO_QUEUE_MAX) {
ret = -EINVAL;
break;
}
Expand Down Expand Up @@ -638,7 +654,8 @@ static int virtio_ccw_cb(SubchDev *sch, CCW1 ccw)
* need to fetch it here. Nothing to do for now, though.
*/
if (dev->revision >= 0 ||
revinfo.revision > virtio_ccw_rev_max(dev)) {
revinfo.revision > virtio_ccw_rev_max(dev) ||
(dev->force_revision_1 && !revinfo.revision)) {
ret = -ENOSYS;
break;
}
Expand Down Expand Up @@ -669,6 +686,12 @@ static void virtio_ccw_device_realize(VirtioCcwDevice *dev, Error **errp)
if (!sch) {
return;
}
if (!virtio_ccw_rev_max(dev) && dev->force_revision_1) {
error_setg(&err, "Invalid value of property max_rev "
"(is %d expected >= 1)", virtio_ccw_rev_max(dev));
error_propagate(errp, err);
return;
}

sch->driver_data = dev;
sch->ccw_cb = virtio_ccw_cb;
Expand Down Expand Up @@ -878,6 +901,24 @@ static void virtio_ccw_rng_realize(VirtioCcwDevice *ccw_dev, Error **errp)
NULL);
}

static void virtio_ccw_crypto_realize(VirtioCcwDevice *ccw_dev, Error **errp)
{
VirtIOCryptoCcw *dev = VIRTIO_CRYPTO_CCW(ccw_dev);
DeviceState *vdev = DEVICE(&dev->vdev);
Error *err = NULL;

qdev_set_parent_bus(vdev, BUS(&ccw_dev->bus));
object_property_set_bool(OBJECT(vdev), true, "realized", &err);
if (err) {
error_propagate(errp, err);
return;
}

object_property_set_link(OBJECT(vdev),
OBJECT(dev->vdev.conf.cryptodev), "cryptodev",
NULL);
}

/* DeviceState to VirtioCcwDevice. Note: used on datapath,
* be careful and test performance if you change this.
*/
Expand Down Expand Up @@ -919,11 +960,11 @@ static void virtio_ccw_notify(DeviceState *d, uint16_t vector)
uint64_t indicators;

/* queue indicators + secondary indicators */
if (vector >= VIRTIO_CCW_QUEUE_MAX + 64) {
if (vector >= VIRTIO_QUEUE_MAX + 64) {
return;
}

if (vector < VIRTIO_CCW_QUEUE_MAX) {
if (vector < VIRTIO_QUEUE_MAX) {
if (!dev->indicators) {
return;
}
Expand Down Expand Up @@ -1278,15 +1319,22 @@ static void virtio_ccw_device_plugged(DeviceState *d, Error **errp)
CcwDevice *ccw_dev = CCW_DEVICE(d);
SubchDev *sch = ccw_dev->sch;
int n = virtio_get_num_queues(vdev);
S390FLICState *flic = s390_get_flic();

if (!virtio_has_feature(vdev->host_features, VIRTIO_F_VERSION_1)) {
dev->max_rev = 0;
}

if (virtio_get_num_queues(vdev) > VIRTIO_CCW_QUEUE_MAX) {
if (virtio_get_num_queues(vdev) > VIRTIO_QUEUE_MAX) {
error_setg(errp, "The number of virtqueues %d "
"exceeds virtio limit %d", n,
VIRTIO_QUEUE_MAX);
return;
}
if (virtio_get_num_queues(vdev) > flic->adapter_routes_max_batch) {
error_setg(errp, "The number of virtqueues %d "
"exceeds ccw limit %d", n,
VIRTIO_CCW_QUEUE_MAX);
"exceeds flic adapter route limit %d", n,
flic->adapter_routes_max_batch);
return;
}

Expand Down Expand Up @@ -1518,6 +1566,48 @@ static const TypeInfo virtio_ccw_rng = {
.class_init = virtio_ccw_rng_class_init,
};

static Property virtio_ccw_crypto_properties[] = {
DEFINE_PROP_CSS_DEV_ID("devno", VirtioCcwDevice, parent_obj.bus_id),
DEFINE_PROP_BIT("ioeventfd", VirtioCcwDevice, flags,
VIRTIO_CCW_FLAG_USE_IOEVENTFD_BIT, true),
DEFINE_PROP_UINT32("max_revision", VirtioCcwDevice, max_rev,
VIRTIO_CCW_MAX_REV),
DEFINE_PROP_END_OF_LIST(),
};

static void virtio_ccw_crypto_instance_init(Object *obj)
{
VirtIOCryptoCcw *dev = VIRTIO_CRYPTO_CCW(obj);
VirtioCcwDevice *ccw_dev = VIRTIO_CCW_DEVICE(obj);

ccw_dev->force_revision_1 = true;
virtio_instance_init_common(obj, &dev->vdev, sizeof(dev->vdev),
TYPE_VIRTIO_CRYPTO);

object_property_add_alias(obj, "cryptodev", OBJECT(&dev->vdev),
"cryptodev", &error_abort);
}

static void virtio_ccw_crypto_class_init(ObjectClass *klass, void *data)
{
DeviceClass *dc = DEVICE_CLASS(klass);
VirtIOCCWDeviceClass *k = VIRTIO_CCW_DEVICE_CLASS(klass);

k->realize = virtio_ccw_crypto_realize;
k->exit = virtio_ccw_exit;
dc->reset = virtio_ccw_reset;
dc->props = virtio_ccw_crypto_properties;
set_bit(DEVICE_CATEGORY_MISC, dc->categories);
}

static const TypeInfo virtio_ccw_crypto = {
.name = TYPE_VIRTIO_CRYPTO_CCW,
.parent = TYPE_VIRTIO_CCW_DEVICE,
.instance_size = sizeof(VirtIOCryptoCcw),
.instance_init = virtio_ccw_crypto_instance_init,
.class_init = virtio_ccw_crypto_class_init,
};

static void virtio_ccw_busdev_realize(DeviceState *dev, Error **errp)
{
VirtioCcwDevice *_dev = (VirtioCcwDevice *)dev;
Expand Down Expand Up @@ -1720,6 +1810,7 @@ static void virtio_ccw_register(void)
#ifdef CONFIG_VHOST_VSOCK
type_register_static(&vhost_vsock_ccw_info);
#endif
type_register_static(&virtio_ccw_crypto);
}

type_init(virtio_ccw_register)
13 changes: 13 additions & 0 deletions hw/s390x/virtio-ccw.h
Expand Up @@ -22,6 +22,7 @@
#endif
#include "hw/virtio/virtio-balloon.h"
#include "hw/virtio/virtio-rng.h"
#include "hw/virtio/virtio-crypto.h"
#include "hw/virtio/virtio-bus.h"
#ifdef CONFIG_VHOST_VSOCK
#include "hw/virtio/vhost-vsock.h"
Expand Down Expand Up @@ -94,6 +95,7 @@ struct VirtioCcwDevice {
IndAddr *indicators2;
IndAddr *summary_indicator;
uint64_t ind_bit;
bool force_revision_1;
};

/* The maximum virtio revision we support. */
Expand Down Expand Up @@ -182,6 +184,17 @@ typedef struct VirtIORNGCcw {
VirtIORNG vdev;
} VirtIORNGCcw;

/* virtio-crypto-ccw */

#define TYPE_VIRTIO_CRYPTO_CCW "virtio-crypto-ccw"
#define VIRTIO_CRYPTO_CCW(obj) \
OBJECT_CHECK(VirtIOCryptoCcw, (obj), TYPE_VIRTIO_CRYPTO_CCW)

typedef struct VirtIOCryptoCcw {
VirtioCcwDevice parent_obj;
VirtIOCrypto vdev;
} VirtIOCryptoCcw;

VirtIODevice *virtio_ccw_get_vdev(SubchDev *sch);

#ifdef CONFIG_VIRTFS
Expand Down

0 comments on commit 2421f38

Please sign in to comment.