diff options
author | Peter Maydell <peter.maydell@linaro.org> | 2016-01-14 12:42:08 +0000 |
---|---|---|
committer | Peter Maydell <peter.maydell@linaro.org> | 2016-01-14 12:42:08 +0000 |
commit | cd0b19a20b80ccacd0579d83ac29ea36d666e67c (patch) | |
tree | c62e5191a0702123eb13c8c5106f144dacce46c7 /hw | |
parent | ed56fdb25692920d2e2915b9c979ad477b0c018e (diff) | |
parent | 88bfa2166ac0b14483a2a2c667499bf3617aebf0 (diff) | |
download | qemu-cd0b19a20b80ccacd0579d83ac29ea36d666e67c.zip qemu-cd0b19a20b80ccacd0579d83ac29ea36d666e67c.tar.gz qemu-cd0b19a20b80ccacd0579d83ac29ea36d666e67c.tar.bz2 |
Merge remote-tracking branch 'remotes/cohuck/tags/s390x-20160113' into staging
This first round of s390x patches includes:
- new compat machine
- remove the old s390-virtio machine
- fixes and some cleanup
# gpg: Signature made Wed 13 Jan 2016 14:55:55 GMT using RSA key ID C6F02FAF
# gpg: Good signature from "Cornelia Huck <huckc@linux.vnet.ibm.com>"
# gpg: aka "Cornelia Huck <cornelia.huck@de.ibm.com>"
* remotes/cohuck/tags/s390x-20160113:
s390x/pci: return real state during listing PCI
virtio-ccw: fix sanity check for vector
s390: Introduce CCW_COMPAT_2_5
s390x/virtio: use qemu_check_nic_model()
s390x/pci: code cleanup
s390x/pci: reject some operations to disabled PCI function
s390x: remove s390-virtio devices
s390x: remove s390-virtio machine
s390x: add 2.6 compat machine
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
Diffstat (limited to 'hw')
-rw-r--r-- | hw/s390x/Makefile.objs | 2 | ||||
-rw-r--r-- | hw/s390x/s390-pci-bus.c | 6 | ||||
-rw-r--r-- | hw/s390x/s390-pci-bus.h | 1 | ||||
-rw-r--r-- | hw/s390x/s390-pci-inst.c | 20 | ||||
-rw-r--r-- | hw/s390x/s390-virtio-bus.c | 758 | ||||
-rw-r--r-- | hw/s390x/s390-virtio-bus.h | 186 | ||||
-rw-r--r-- | hw/s390x/s390-virtio-ccw.c | 27 | ||||
-rw-r--r-- | hw/s390x/s390-virtio.c | 168 | ||||
-rw-r--r-- | hw/s390x/virtio-ccw.c | 3 |
9 files changed, 45 insertions, 1126 deletions
diff --git a/hw/s390x/Makefile.objs b/hw/s390x/Makefile.objs index 527d754..2203617 100644 --- a/hw/s390x/Makefile.objs +++ b/hw/s390x/Makefile.objs @@ -1,4 +1,4 @@ -obj-y = s390-virtio-bus.o s390-virtio.o +obj-y += s390-virtio.o obj-y += s390-virtio-hcall.o obj-y += sclp.o obj-y += event-facility.o diff --git a/hw/s390x/s390-pci-bus.c b/hw/s390x/s390-pci-bus.c index 8de35ff..132588b 100644 --- a/hw/s390x/s390-pci-bus.c +++ b/hw/s390x/s390-pci-bus.c @@ -317,7 +317,7 @@ static IOMMUTLBEntry s390_translate_iommu(MemoryRegion *iommu, hwaddr addr, .perm = IOMMU_NONE, }; - if (!pbdev->configured || !pbdev->pdev) { + if (!pbdev->configured || !pbdev->pdev || !(pbdev->fh & FH_ENABLED)) { return ret; } @@ -428,6 +428,10 @@ static void s390_msi_ctrl_write(void *opaque, hwaddr addr, uint64_t data, return; } + if (!(pbdev->fh & FH_ENABLED)) { + return; + } + ind_bit = pbdev->routes.adapter.ind_offset; sum_bit = pbdev->routes.adapter.summary_offset; diff --git a/hw/s390x/s390-pci-bus.h b/hw/s390x/s390-pci-bus.h index 80345da..d8ddb77 100644 --- a/hw/s390x/s390-pci-bus.h +++ b/hw/s390x/s390-pci-bus.h @@ -23,6 +23,7 @@ #define TYPE_S390_PCI_HOST_BRIDGE "s390-pcihost" #define FH_VIRT 0x00ff0000 #define ENABLE_BIT_OFFSET 31 +#define FH_ENABLED (1 << ENABLE_BIT_OFFSET) #define S390_PCIPT_ADAPTER 2 #define S390_PCI_HOST_BRIDGE(obj) \ diff --git a/hw/s390x/s390-pci-inst.c b/hw/s390x/s390-pci-inst.c index 8c1dc82..1a6a3e7 100644 --- a/hw/s390x/s390-pci-inst.c +++ b/hw/s390x/s390-pci-inst.c @@ -105,7 +105,8 @@ static int list_pci(ClpReqRspListPci *rrb, uint8_t *cc) pci_get_word(pbdev->pdev->config + PCI_DEVICE_ID)); stw_p(&rrb->response.fh_list[idx - resume_token].vendor_id, pci_get_word(pbdev->pdev->config + PCI_VENDOR_ID)); - stl_p(&rrb->response.fh_list[idx - resume_token].config, 0x80000000); + stl_p(&rrb->response.fh_list[idx - resume_token].config, + pbdev->configured << 31); stl_p(&rrb->response.fh_list[idx - resume_token].fid, pbdev->fid); stl_p(&rrb->response.fh_list[idx - resume_token].fh, pbdev->fh); @@ -208,12 +209,12 @@ int clp_service_call(S390CPU *cpu, uint8_t r2) switch (reqsetpci->oc) { case CLP_SET_ENABLE_PCI_FN: - pbdev->fh = pbdev->fh | 1 << ENABLE_BIT_OFFSET; + pbdev->fh = pbdev->fh | FH_ENABLED; stl_p(&ressetpci->fh, pbdev->fh); stw_p(&ressetpci->hdr.rsp, CLP_RC_OK); break; case CLP_SET_DISABLE_PCI_FN: - pbdev->fh = pbdev->fh & ~(1 << ENABLE_BIT_OFFSET); + pbdev->fh = pbdev->fh & ~FH_ENABLED; pbdev->error_state = false; pbdev->lgstg_blocked = false; stl_p(&ressetpci->fh, pbdev->fh); @@ -313,7 +314,7 @@ int pcilg_service_call(S390CPU *cpu, uint8_t r1, uint8_t r2) offset = env->regs[r2 + 1]; pbdev = s390_pci_find_dev_by_fh(fh); - if (!pbdev) { + if (!pbdev || !(pbdev->fh & FH_ENABLED)) { DPRINTF("pcilg no pci dev\n"); setcc(cpu, ZPCI_PCI_LS_INVAL_HANDLE); return 0; @@ -430,7 +431,7 @@ int pcistg_service_call(S390CPU *cpu, uint8_t r1, uint8_t r2) offset = env->regs[r2 + 1]; pbdev = s390_pci_find_dev_by_fh(fh); - if (!pbdev) { + if (!pbdev || !(pbdev->fh & FH_ENABLED)) { DPRINTF("pcistg no pci dev\n"); setcc(cpu, ZPCI_PCI_LS_INVAL_HANDLE); return 0; @@ -521,8 +522,7 @@ int rpcit_service_call(S390CPU *cpu, uint8_t r1, uint8_t r2) end = start + env->regs[r2 + 1]; pbdev = s390_pci_find_dev_by_fh(fh); - - if (!pbdev) { + if (!pbdev || !(pbdev->fh & FH_ENABLED)) { DPRINTF("rpcit no pci dev\n"); setcc(cpu, ZPCI_PCI_LS_INVAL_HANDLE); goto out; @@ -586,7 +586,7 @@ int pcistb_service_call(S390CPU *cpu, uint8_t r1, uint8_t r3, uint64_t gaddr, } pbdev = s390_pci_find_dev_by_fh(fh); - if (!pbdev) { + if (!pbdev || !(pbdev->fh & FH_ENABLED)) { DPRINTF("pcistb no pci dev fh 0x%x\n", fh); setcc(cpu, ZPCI_PCI_LS_INVAL_HANDLE); return 0; @@ -727,7 +727,7 @@ int mpcifc_service_call(S390CPU *cpu, uint8_t r1, uint64_t fiba, uint8_t ar) } pbdev = s390_pci_find_dev_by_fh(fh); - if (!pbdev) { + if (!pbdev || !(pbdev->fh & FH_ENABLED)) { DPRINTF("mpcifc no pci dev fh 0x%x\n", fh); setcc(cpu, ZPCI_PCI_LS_INVAL_HANDLE); return 0; @@ -819,7 +819,7 @@ int stpcifc_service_call(S390CPU *cpu, uint8_t r1, uint64_t fiba, uint8_t ar) ((uint32_t)pbdev->sum << 7) | pbdev->routes.adapter.summary_offset; stl_p(&fib.data, data); - if (pbdev->fh >> ENABLE_BIT_OFFSET) { + if (pbdev->fh & FH_ENABLED) { fib.fc |= 0x80; } diff --git a/hw/s390x/s390-virtio-bus.c b/hw/s390x/s390-virtio-bus.c deleted file mode 100644 index 98cb129..0000000 --- a/hw/s390x/s390-virtio-bus.c +++ /dev/null @@ -1,758 +0,0 @@ -/* - * QEMU S390 virtio target - * - * Copyright (c) 2009 Alexander Graf <agraf@suse.de> - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library; if not, see <http://www.gnu.org/licenses/>. - */ - -#include "hw/hw.h" -#include "sysemu/block-backend.h" -#include "sysemu/sysemu.h" -#include "hw/boards.h" -#include "hw/loader.h" -#include "elf.h" -#include "hw/virtio/virtio.h" -#include "hw/virtio/virtio-rng.h" -#include "hw/virtio/virtio-serial.h" -#include "hw/virtio/virtio-net.h" -#include "hw/virtio/vhost-scsi.h" -#include "hw/sysbus.h" -#include "sysemu/kvm.h" - -#include "hw/s390x/s390-virtio-bus.h" -#include "hw/virtio/virtio-bus.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 VIRTIO_S390_QUEUE_MAX 64 - -static void virtio_s390_bus_new(VirtioBusState *bus, size_t bus_size, - VirtIOS390Device *dev); - -static const TypeInfo s390_virtio_bus_info = { - .name = TYPE_S390_VIRTIO_BUS, - .parent = TYPE_BUS, - .instance_size = sizeof(VirtIOS390Bus), -}; - -static ram_addr_t s390_virtio_device_num_vq(VirtIOS390Device *dev); - -/* length of VirtIO device pages */ -const hwaddr virtio_size = S390_DEVICE_PAGES * TARGET_PAGE_SIZE; - -static void s390_virtio_bus_reset(void *opaque) -{ - VirtIOS390Bus *bus = opaque; - bus->next_ring = bus->dev_page + TARGET_PAGE_SIZE; -} - -void s390_virtio_reset_idx(VirtIOS390Device *dev) -{ - int i; - hwaddr idx_addr; - uint8_t num_vq; - - num_vq = s390_virtio_device_num_vq(dev); - for (i = 0; i < num_vq; i++) { - idx_addr = virtio_queue_get_avail_addr(dev->vdev, i) + - VIRTIO_VRING_AVAIL_IDX_OFFS; - address_space_stw(&address_space_memory, idx_addr, 0, - MEMTXATTRS_UNSPECIFIED, NULL); - idx_addr = virtio_queue_get_avail_addr(dev->vdev, i) + - virtio_queue_get_avail_size(dev->vdev, i); - address_space_stw(&address_space_memory, idx_addr, 0, - MEMTXATTRS_UNSPECIFIED, NULL); - idx_addr = virtio_queue_get_used_addr(dev->vdev, i) + - VIRTIO_VRING_USED_IDX_OFFS; - address_space_stw(&address_space_memory, idx_addr, 0, - MEMTXATTRS_UNSPECIFIED, NULL); - idx_addr = virtio_queue_get_used_addr(dev->vdev, i) + - virtio_queue_get_used_size(dev->vdev, i); - address_space_stw(&address_space_memory, idx_addr, 0, - MEMTXATTRS_UNSPECIFIED, NULL); - } -} - -VirtIOS390Bus *s390_virtio_bus_init(ram_addr_t *ram_size) -{ - VirtIOS390Bus *bus; - BusState *_bus; - DeviceState *dev; - - /* Create bridge device */ - dev = qdev_create(NULL, "s390-virtio-bridge"); - qdev_init_nofail(dev); - - /* Create bus on bridge device */ - - _bus = qbus_create(TYPE_S390_VIRTIO_BUS, dev, "s390-virtio"); - bus = DO_UPCAST(VirtIOS390Bus, bus, _bus); - - bus->dev_page = *ram_size; - bus->dev_offs = bus->dev_page; - bus->next_ring = bus->dev_page + TARGET_PAGE_SIZE; - - /* Enable hotplugging */ - qbus_set_hotplug_handler(_bus, dev, &error_abort); - - /* Allocate RAM for VirtIO device pages (descriptors, queues, rings) */ - *ram_size += S390_DEVICE_PAGES * TARGET_PAGE_SIZE; - - qemu_register_reset(s390_virtio_bus_reset, bus); - return bus; -} - -static void s390_virtio_device_init(VirtIOS390Device *dev, - VirtIODevice *vdev) -{ - VirtIOS390Bus *bus; - int dev_len; - - bus = DO_UPCAST(VirtIOS390Bus, bus, dev->qdev.parent_bus); - dev->vdev = vdev; - dev->dev_offs = bus->dev_offs; - dev->feat_len = sizeof(uint32_t); /* always keep 32 bits features */ - - dev_len = VIRTIO_DEV_OFFS_CONFIG; - dev_len += s390_virtio_device_num_vq(dev) * VIRTIO_VQCONFIG_LEN; - dev_len += dev->feat_len * 2; - dev_len += virtio_bus_get_vdev_config_len(&dev->bus); - - bus->dev_offs += dev_len; - - s390_virtio_device_sync(dev); - s390_virtio_reset_idx(dev); - if (dev->qdev.hotplugged) { - s390_virtio_irq(VIRTIO_PARAM_DEV_ADD, dev->dev_offs); - } -} - -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_netclient_name(&dev->vdev, qdev->id, - object_get_typename(OBJECT(qdev))); - qdev_set_parent_bus(vdev, BUS(&s390_dev->bus)); - object_property_set_bool(OBJECT(vdev), true, "realized", &err); - if (err) { - error_propagate(errp, err); - return; - } - - s390_virtio_device_init(s390_dev, VIRTIO_DEVICE(vdev)); -} - -static void s390_virtio_net_instance_init(Object *obj) -{ - VirtIONetS390 *dev = VIRTIO_NET_S390(obj); - - virtio_instance_init_common(obj, &dev->vdev, sizeof(dev->vdev), - TYPE_VIRTIO_NET); - object_property_add_alias(obj, "bootindex", OBJECT(&dev->vdev), - "bootindex", &error_abort); -} - -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)); - object_property_set_bool(OBJECT(vdev), true, "realized", &err); - if (err) { - error_propagate(errp, err); - return; - } - s390_virtio_device_init(s390_dev, VIRTIO_DEVICE(vdev)); -} - -static void s390_virtio_blk_instance_init(Object *obj) -{ - VirtIOBlkS390 *dev = VIRTIO_BLK_S390(obj); - - virtio_instance_init_common(obj, &dev->vdev, sizeof(dev->vdev), - TYPE_VIRTIO_BLK); - object_property_add_alias(obj, "iothread", OBJECT(&dev->vdev),"iothread", - &error_abort); - object_property_add_alias(obj, "bootindex", OBJECT(&dev->vdev), - "bootindex", &error_abort); -} - -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; - char *bus_name; - - bus = DO_UPCAST(VirtIOS390Bus, bus, qdev->parent_bus); - - /* - * For command line compatibility, this sets the virtio-serial-device bus - * name as before. - */ - if (qdev->id) { - bus_name = g_strdup_printf("%s.0", qdev->id); - virtio_device_set_child_bus_name(VIRTIO_DEVICE(vdev), bus_name); - g_free(bus_name); - } - - qdev_set_parent_bus(vdev, BUS(&s390_dev->bus)); - object_property_set_bool(OBJECT(vdev), true, "realized", &err); - if (err) { - error_propagate(errp, err); - return; - } - - s390_virtio_device_init(s390_dev, VIRTIO_DEVICE(vdev)); - bus->console = s390_dev; -} - -static void s390_virtio_serial_instance_init(Object *obj) -{ - VirtIOSerialS390 *dev = VIRTIO_SERIAL_S390(obj); - - virtio_instance_init_common(obj, &dev->vdev, sizeof(dev->vdev), - TYPE_VIRTIO_SERIAL); -} - -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; - - /* - * For command line compatibility, this sets the virtio-scsi-device bus - * name as before. - */ - if (qdev->id) { - bus_name = g_strdup_printf("%s.0", qdev->id); - virtio_device_set_child_bus_name(VIRTIO_DEVICE(vdev), bus_name); - g_free(bus_name); - } - - qdev_set_parent_bus(vdev, BUS(&s390_dev->bus)); - object_property_set_bool(OBJECT(vdev), true, "realized", &err); - if (err) { - error_propagate(errp, err); - return; - } - - s390_virtio_device_init(s390_dev, VIRTIO_DEVICE(vdev)); -} - -static void s390_virtio_scsi_instance_init(Object *obj) -{ - VirtIOSCSIS390 *dev = VIRTIO_SCSI_S390(obj); - - virtio_instance_init_common(obj, &dev->vdev, sizeof(dev->vdev), - TYPE_VIRTIO_SCSI); -} - -#ifdef CONFIG_VHOST_SCSI -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)); - object_property_set_bool(OBJECT(vdev), true, "realized", &err); - if (err) { - error_propagate(errp, err); - return; - } - - s390_virtio_device_init(s390_dev, VIRTIO_DEVICE(vdev)); -} - -static void s390_vhost_scsi_instance_init(Object *obj) -{ - VHostSCSIS390 *dev = VHOST_SCSI_S390(obj); - - virtio_instance_init_common(obj, &dev->vdev, sizeof(dev->vdev), - TYPE_VHOST_SCSI); -} -#endif - - -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)); - 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); - - s390_virtio_device_init(s390_dev, VIRTIO_DEVICE(vdev)); -} - -static void s390_virtio_rng_instance_init(Object *obj) -{ - VirtIORNGS390 *dev = VIRTIO_RNG_S390(obj); - - virtio_instance_init_common(obj, &dev->vdev, sizeof(dev->vdev), - TYPE_VIRTIO_RNG); - object_property_add_alias(obj, "rng", OBJECT(&dev->vdev), - "rng", &error_abort); -} - -static uint64_t s390_virtio_device_vq_token(VirtIOS390Device *dev, int vq) -{ - ram_addr_t token_off; - - token_off = (dev->dev_offs + VIRTIO_DEV_OFFS_CONFIG) + - (vq * VIRTIO_VQCONFIG_LEN) + - VIRTIO_VQCONFIG_OFFS_TOKEN; - - return address_space_ldq_be(&address_space_memory, token_off, - MEMTXATTRS_UNSPECIFIED, NULL); -} - -static ram_addr_t s390_virtio_device_num_vq(VirtIOS390Device *dev) -{ - VirtIODevice *vdev = dev->vdev; - int num_vq; - - for (num_vq = 0; num_vq < VIRTIO_S390_QUEUE_MAX; num_vq++) { - if (!virtio_queue_get_num(vdev, num_vq)) { - break; - } - } - - return num_vq; -} - -static ram_addr_t s390_virtio_next_ring(VirtIOS390Bus *bus) -{ - ram_addr_t r = bus->next_ring; - - bus->next_ring += VIRTIO_RING_LEN; - return r; -} - -void s390_virtio_device_sync(VirtIOS390Device *dev) -{ - VirtIOS390Bus *bus = DO_UPCAST(VirtIOS390Bus, bus, dev->qdev.parent_bus); - ram_addr_t cur_offs; - uint8_t num_vq; - int i; - - virtio_reset(dev->vdev); - - /* Sync dev space */ - address_space_stb(&address_space_memory, - dev->dev_offs + VIRTIO_DEV_OFFS_TYPE, - dev->vdev->device_id, - MEMTXATTRS_UNSPECIFIED, - NULL); - - address_space_stb(&address_space_memory, - dev->dev_offs + VIRTIO_DEV_OFFS_NUM_VQ, - s390_virtio_device_num_vq(dev), - MEMTXATTRS_UNSPECIFIED, - NULL); - address_space_stb(&address_space_memory, - dev->dev_offs + VIRTIO_DEV_OFFS_FEATURE_LEN, - dev->feat_len, - MEMTXATTRS_UNSPECIFIED, - NULL); - - address_space_stb(&address_space_memory, - dev->dev_offs + VIRTIO_DEV_OFFS_CONFIG_LEN, - dev->vdev->config_len, - MEMTXATTRS_UNSPECIFIED, - NULL); - - num_vq = s390_virtio_device_num_vq(dev); - address_space_stb(&address_space_memory, - dev->dev_offs + VIRTIO_DEV_OFFS_NUM_VQ, num_vq, - MEMTXATTRS_UNSPECIFIED, NULL); - - /* Sync virtqueues */ - for (i = 0; i < num_vq; i++) { - ram_addr_t vq = (dev->dev_offs + VIRTIO_DEV_OFFS_CONFIG) + - (i * VIRTIO_VQCONFIG_LEN); - ram_addr_t vring; - - vring = s390_virtio_next_ring(bus); - virtio_queue_set_addr(dev->vdev, i, vring); - virtio_queue_set_vector(dev->vdev, i, i); - address_space_stq_be(&address_space_memory, - vq + VIRTIO_VQCONFIG_OFFS_ADDRESS, vring, - MEMTXATTRS_UNSPECIFIED, NULL); - address_space_stw_be(&address_space_memory, - vq + VIRTIO_VQCONFIG_OFFS_NUM, - virtio_queue_get_num(dev->vdev, i), - MEMTXATTRS_UNSPECIFIED, - NULL); - } - - cur_offs = dev->dev_offs; - cur_offs += VIRTIO_DEV_OFFS_CONFIG; - cur_offs += num_vq * VIRTIO_VQCONFIG_LEN; - - /* Sync feature bitmap */ - address_space_stl_le(&address_space_memory, cur_offs, - dev->vdev->host_features, - MEMTXATTRS_UNSPECIFIED, NULL); - - dev->feat_offs = cur_offs + dev->feat_len; - cur_offs += dev->feat_len * 2; - - /* Sync config space */ - virtio_bus_get_vdev_config(&dev->bus, dev->vdev->config); - - cpu_physical_memory_write(cur_offs, - dev->vdev->config, dev->vdev->config_len); - cur_offs += dev->vdev->config_len; -} - -void s390_virtio_device_update_status(VirtIOS390Device *dev) -{ - VirtIODevice *vdev = dev->vdev; - uint32_t features; - - virtio_set_status(vdev, - address_space_ldub(&address_space_memory, - dev->dev_offs + VIRTIO_DEV_OFFS_STATUS, - MEMTXATTRS_UNSPECIFIED, NULL)); - - /* Update guest supported feature bitmap */ - - features = bswap32(address_space_ldl_be(&address_space_memory, - dev->feat_offs, - MEMTXATTRS_UNSPECIFIED, NULL)); - virtio_set_features(vdev, features); -} - -/* Find a device by vring address */ -VirtIOS390Device *s390_virtio_bus_find_vring(VirtIOS390Bus *bus, - ram_addr_t mem, - int *vq_num) -{ - BusChild *kid; - int i; - - QTAILQ_FOREACH(kid, &bus->bus.children, sibling) { - VirtIOS390Device *dev = (VirtIOS390Device *)kid->child; - - for (i = 0; i < VIRTIO_S390_QUEUE_MAX; i++) { - if (!virtio_queue_get_addr(dev->vdev, i)) - break; - if (virtio_queue_get_addr(dev->vdev, i) == mem) { - if (vq_num) { - *vq_num = i; - } - return dev; - } - } - } - - return NULL; -} - -/* Find a device by device descriptor location */ -VirtIOS390Device *s390_virtio_bus_find_mem(VirtIOS390Bus *bus, ram_addr_t mem) -{ - BusChild *kid; - - QTAILQ_FOREACH(kid, &bus->bus.children, sibling) { - VirtIOS390Device *dev = (VirtIOS390Device *)kid->child; - if (dev->dev_offs == mem) { - return dev; - } - } - - return NULL; -} - -/* DeviceState to VirtIOS390Device. Note: used on datapath, - * be careful and test performance if you change this. - */ -static inline VirtIOS390Device *to_virtio_s390_device_fast(DeviceState *d) -{ - return container_of(d, VirtIOS390Device, qdev); -} - -/* DeviceState to VirtIOS390Device. TODO: use QOM. */ -static inline VirtIOS390Device *to_virtio_s390_device(DeviceState *d) -{ - return container_of(d, VirtIOS390Device, qdev); -} - -static void virtio_s390_notify(DeviceState *d, uint16_t vector) -{ - VirtIOS390Device *dev = to_virtio_s390_device_fast(d); - uint64_t token = s390_virtio_device_vq_token(dev, vector); - - s390_virtio_irq(0, token); -} - -static void virtio_s390_device_plugged(DeviceState *d, Error **errp) -{ - VirtIOS390Device *dev = to_virtio_s390_device(d); - VirtIODevice *vdev = virtio_bus_get_device(&dev->bus); - int n = virtio_get_num_queues(vdev); - - if (n > VIRTIO_S390_QUEUE_MAX) { - error_setg(errp, "The nubmer of virtqueues %d " - "exceeds s390 limit %d", n, - VIRTIO_S390_QUEUE_MAX); - } -} - -/**************** S390 Virtio Bus Device Descriptions *******************/ - -static void s390_virtio_net_class_init(ObjectClass *klass, void *data) -{ - DeviceClass *dc = DEVICE_CLASS(klass); - VirtIOS390DeviceClass *k = VIRTIO_S390_DEVICE_CLASS(klass); - - k->realize = s390_virtio_net_realize; - set_bit(DEVICE_CATEGORY_NETWORK, dc->categories); -} - -static const TypeInfo s390_virtio_net = { - .name = TYPE_VIRTIO_NET_S390, - .parent = TYPE_VIRTIO_S390_DEVICE, - .instance_size = sizeof(VirtIONetS390), - .instance_init = s390_virtio_net_instance_init, - .class_init = s390_virtio_net_class_init, -}; - -static void s390_virtio_blk_class_init(ObjectClass *klass, void *data) -{ - VirtIOS390DeviceClass *k = VIRTIO_S390_DEVICE_CLASS(klass); - DeviceClass *dc = DEVICE_CLASS(klass); - - k->realize = s390_virtio_blk_realize; - set_bit(DEVICE_CATEGORY_STORAGE, dc->categories); -} - -static const TypeInfo s390_virtio_blk = { - .name = "virtio-blk-s390", - .parent = TYPE_VIRTIO_S390_DEVICE, - .instance_size = sizeof(VirtIOBlkS390), - .instance_init = s390_virtio_blk_instance_init, - .class_init = s390_virtio_blk_class_init, -}; - -static void s390_virtio_serial_class_init(ObjectClass *klass, void *data) -{ - DeviceClass *dc = DEVICE_CLASS(klass); - VirtIOS390DeviceClass *k = VIRTIO_S390_DEVICE_CLASS(klass); - - k->realize = s390_virtio_serial_realize; - set_bit(DEVICE_CATEGORY_INPUT, dc->categories); -} - -static const TypeInfo s390_virtio_serial = { - .name = TYPE_VIRTIO_SERIAL_S390, - .parent = TYPE_VIRTIO_S390_DEVICE, - .instance_size = sizeof(VirtIOSerialS390), - .instance_init = s390_virtio_serial_instance_init, - .class_init = s390_virtio_serial_class_init, -}; - -static void s390_virtio_rng_class_init(ObjectClass *klass, void *data) -{ - DeviceClass *dc = DEVICE_CLASS(klass); - VirtIOS390DeviceClass *k = VIRTIO_S390_DEVICE_CLASS(klass); - - k->realize = s390_virtio_rng_realize; - set_bit(DEVICE_CATEGORY_MISC, dc->categories); -} - -static const TypeInfo s390_virtio_rng = { - .name = TYPE_VIRTIO_RNG_S390, - .parent = TYPE_VIRTIO_S390_DEVICE, - .instance_size = sizeof(VirtIORNGS390), - .instance_init = s390_virtio_rng_instance_init, - .class_init = s390_virtio_rng_class_init, -}; - -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); - - _info->realize(_dev, errp); -} - -static void s390_virtio_busdev_reset(DeviceState *dev) -{ - VirtIOS390Device *_dev = (VirtIOS390Device *)dev; - - virtio_reset(_dev->vdev); -} - -static void virtio_s390_device_class_init(ObjectClass *klass, void *data) -{ - DeviceClass *dc = DEVICE_CLASS(klass); - - dc->realize = s390_virtio_busdev_realize; - dc->bus_type = TYPE_S390_VIRTIO_BUS; - dc->reset = s390_virtio_busdev_reset; -} - -static const TypeInfo virtio_s390_device_info = { - .name = TYPE_VIRTIO_S390_DEVICE, - .parent = TYPE_DEVICE, - .instance_size = sizeof(VirtIOS390Device), - .class_init = virtio_s390_device_class_init, - .class_size = sizeof(VirtIOS390DeviceClass), - .abstract = true, -}; - -static void s390_virtio_scsi_class_init(ObjectClass *klass, void *data) -{ - DeviceClass *dc = DEVICE_CLASS(klass); - VirtIOS390DeviceClass *k = VIRTIO_S390_DEVICE_CLASS(klass); - - k->realize = s390_virtio_scsi_realize; - set_bit(DEVICE_CATEGORY_STORAGE, dc->categories); -} - -static const TypeInfo s390_virtio_scsi = { - .name = TYPE_VIRTIO_SCSI_S390, - .parent = TYPE_VIRTIO_S390_DEVICE, - .instance_size = sizeof(VirtIOSCSIS390), - .instance_init = s390_virtio_scsi_instance_init, - .class_init = s390_virtio_scsi_class_init, -}; - -#ifdef CONFIG_VHOST_SCSI -static void s390_vhost_scsi_class_init(ObjectClass *klass, void *data) -{ - DeviceClass *dc = DEVICE_CLASS(klass); - VirtIOS390DeviceClass *k = VIRTIO_S390_DEVICE_CLASS(klass); - - k->realize = s390_vhost_scsi_realize; - set_bit(DEVICE_CATEGORY_STORAGE, dc->categories); -} - -static const TypeInfo s390_vhost_scsi = { - .name = TYPE_VHOST_SCSI_S390, - .parent = TYPE_VIRTIO_S390_DEVICE, - .instance_size = sizeof(VHostSCSIS390), - .instance_init = s390_vhost_scsi_instance_init, - .class_init = s390_vhost_scsi_class_init, -}; -#endif - -/***************** S390 Virtio Bus Bridge Device *******************/ -/* Only required to have the virtio bus as child in the system bus */ - -static int s390_virtio_bridge_init(SysBusDevice *dev) -{ - /* nothing */ - return 0; -} - -static void s390_virtio_bridge_class_init(ObjectClass *klass, void *data) -{ - SysBusDeviceClass *k = SYS_BUS_DEVICE_CLASS(klass); - DeviceClass *dc = DEVICE_CLASS(klass); - - k->init = s390_virtio_bridge_init; - set_bit(DEVICE_CATEGORY_BRIDGE, dc->categories); -} - -static const TypeInfo s390_virtio_bridge_info = { - .name = "s390-virtio-bridge", - .parent = TYPE_SYS_BUS_DEVICE, - .instance_size = sizeof(SysBusDevice), - .class_init = s390_virtio_bridge_class_init, - .interfaces = (InterfaceInfo[]) { - { TYPE_HOTPLUG_HANDLER }, - { } - } -}; - -/* virtio-s390-bus */ - -static void virtio_s390_bus_new(VirtioBusState *bus, size_t bus_size, - VirtIOS390Device *dev) -{ - DeviceState *qdev = DEVICE(dev); - char virtio_bus_name[] = "virtio-bus"; - - qbus_create_inplace(bus, bus_size, TYPE_VIRTIO_S390_BUS, - qdev, virtio_bus_name); -} - -static void virtio_s390_bus_class_init(ObjectClass *klass, void *data) -{ - VirtioBusClass *k = VIRTIO_BUS_CLASS(klass); - BusClass *bus_class = BUS_CLASS(klass); - bus_class->max_dev = 1; - k->notify = virtio_s390_notify; - k->device_plugged = virtio_s390_device_plugged; -} - -static const TypeInfo virtio_s390_bus_info = { - .name = TYPE_VIRTIO_S390_BUS, - .parent = TYPE_VIRTIO_BUS, - .instance_size = sizeof(VirtioS390BusState), - .class_init = virtio_s390_bus_class_init, -}; - -static void s390_virtio_register_types(void) -{ - type_register_static(&virtio_s390_bus_info); - type_register_static(&s390_virtio_bus_info); - type_register_static(&virtio_s390_device_info); - type_register_static(&s390_virtio_serial); - type_register_static(&s390_virtio_blk); - type_register_static(&s390_virtio_net); - type_register_static(&s390_virtio_scsi); -#ifdef CONFIG_VHOST_SCSI - type_register_static(&s390_vhost_scsi); -#endif - type_register_static(&s390_virtio_rng); - type_register_static(&s390_virtio_bridge_info); -} - -type_init(s390_virtio_register_types) diff --git a/hw/s390x/s390-virtio-bus.h b/hw/s390x/s390-virtio-bus.h deleted file mode 100644 index 7ad295e..0000000 --- a/hw/s390x/s390-virtio-bus.h +++ /dev/null @@ -1,186 +0,0 @@ -/* - * QEMU S390x VirtIO BUS definitions - * - * Copyright (c) 2009 Alexander Graf <agraf@suse.de> - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library; if not, see <http://www.gnu.org/licenses/>. - */ -#ifndef HW_S390_VIRTIO_BUS_H -#define HW_S390_VIRTIO_BUS_H 1 - -#include <stddef.h> - -#include "standard-headers/asm-s390/kvm_virtio.h" -#include "standard-headers/linux/virtio_ring.h" -#include "hw/virtio/virtio-blk.h" -#include "hw/virtio/virtio-net.h" -#include "hw/virtio/virtio-rng.h" -#include "hw/virtio/virtio-serial.h" -#include "hw/virtio/virtio-scsi.h" -#include "hw/virtio/virtio-bus.h" -#ifdef CONFIG_VHOST_SCSI -#include "hw/virtio/vhost-scsi.h" -#endif - -typedef struct kvm_device_desc KvmDeviceDesc; - -#define VIRTIO_DEV_OFFS_TYPE offsetof(KvmDeviceDesc, type) -#define VIRTIO_DEV_OFFS_NUM_VQ offsetof(KvmDeviceDesc, num_vq) -#define VIRTIO_DEV_OFFS_FEATURE_LEN offsetof(KvmDeviceDesc, feature_len) -#define VIRTIO_DEV_OFFS_CONFIG_LEN offsetof(KvmDeviceDesc, config_len) -#define VIRTIO_DEV_OFFS_STATUS offsetof(KvmDeviceDesc, status) -#define VIRTIO_DEV_OFFS_CONFIG offsetof(KvmDeviceDesc, config) - -typedef struct kvm_vqconfig KvmVqConfig; -#define VIRTIO_VQCONFIG_OFFS_TOKEN offsetof(KvmVqConfig,token) /* 64 bit */ -#define VIRTIO_VQCONFIG_OFFS_ADDRESS offsetof(KvmVqConfig, address) /* 64 bit */ -#define VIRTIO_VQCONFIG_OFFS_NUM offsetof(KvmVqConfig, num) /* 16 bit */ -#define VIRTIO_VQCONFIG_LEN sizeof(KvmVqConfig) - -#define VIRTIO_RING_LEN (TARGET_PAGE_SIZE * 3) -#define VIRTIO_VRING_AVAIL_IDX_OFFS offsetof(struct vring_avail, idx) -#define VIRTIO_VRING_USED_IDX_OFFS offsetof(struct vring_used, idx) -#define S390_DEVICE_PAGES 512 - -#define TYPE_VIRTIO_S390_DEVICE "virtio-s390-device" -#define VIRTIO_S390_DEVICE(obj) \ - OBJECT_CHECK(VirtIOS390Device, (obj), TYPE_VIRTIO_S390_DEVICE) -#define VIRTIO_S390_DEVICE_CLASS(klass) \ - OBJECT_CLASS_CHECK(VirtIOS390DeviceClass, (klass), TYPE_VIRTIO_S390_DEVICE) -#define VIRTIO_S390_DEVICE_GET_CLASS(obj) \ - OBJECT_GET_CLASS(VirtIOS390DeviceClass, (obj), TYPE_VIRTIO_S390_DEVICE) - -#define TYPE_S390_VIRTIO_BUS "s390-virtio-bus" -#define S390_VIRTIO_BUS(obj) \ - OBJECT_CHECK(VirtIOS390Bus, (obj), TYPE_S390_VIRTIO_BUS) - -/* virtio-s390-bus */ - -typedef struct VirtioBusState VirtioS390BusState; -typedef struct VirtioBusClass VirtioS390BusClass; - -#define TYPE_VIRTIO_S390_BUS "virtio-s390-bus" -#define VIRTIO_S390_BUS(obj) \ - OBJECT_CHECK(VirtioS390BusState, (obj), TYPE_VIRTIO_S390_BUS) -#define VIRTIO_S390_BUS_GET_CLASS(obj) \ - OBJECT_GET_CLASS(VirtioS390BusClass, obj, TYPE_VIRTIO_S390_BUS) -#define VIRTIO_S390_BUS_CLASS(klass) \ - OBJECT_CLASS_CHECK(VirtioS390BusClass, klass, TYPE_VIRTIO_S390_BUS) - - -typedef struct VirtIOS390Device VirtIOS390Device; - -typedef struct VirtIOS390DeviceClass { - DeviceClass qdev; - void (*realize)(VirtIOS390Device *dev, Error **errp); -} VirtIOS390DeviceClass; - -struct VirtIOS390Device { - DeviceState qdev; - ram_addr_t dev_offs; - ram_addr_t feat_offs; - uint8_t feat_len; - VirtIODevice *vdev; - VirtioBusState bus; -}; - -typedef struct VirtIOS390Bus { - BusState bus; - - VirtIOS390Device *console; - ram_addr_t dev_page; - ram_addr_t dev_offs; - ram_addr_t next_ring; -} VirtIOS390Bus; - - -void s390_virtio_device_update_status(VirtIOS390Device *dev); - -VirtIOS390Bus *s390_virtio_bus_init(ram_addr_t *ram_size); - -VirtIOS390Device *s390_virtio_bus_find_vring(VirtIOS390Bus *bus, - ram_addr_t mem, int *vq_num); -VirtIOS390Device *s390_virtio_bus_find_mem(VirtIOS390Bus *bus, ram_addr_t mem); -void s390_virtio_device_sync(VirtIOS390Device *dev); -void s390_virtio_reset_idx(VirtIOS390Device *dev); - -/* virtio-blk-s390 */ - -#define TYPE_VIRTIO_BLK_S390 "virtio-blk-s390" -#define VIRTIO_BLK_S390(obj) \ - OBJECT_CHECK(VirtIOBlkS390, (obj), TYPE_VIRTIO_BLK_S390) - -typedef struct VirtIOBlkS390 { - VirtIOS390Device parent_obj; - VirtIOBlock vdev; -} VirtIOBlkS390; - -/* virtio-scsi-s390 */ - -#define TYPE_VIRTIO_SCSI_S390 "virtio-scsi-s390" -#define VIRTIO_SCSI_S390(obj) \ - OBJECT_CHECK(VirtIOSCSIS390, (obj), TYPE_VIRTIO_SCSI_S390) - -typedef struct VirtIOSCSIS390 { - VirtIOS390Device parent_obj; - VirtIOSCSI vdev; -} VirtIOSCSIS390; - -/* virtio-serial-s390 */ - -#define TYPE_VIRTIO_SERIAL_S390 "virtio-serial-s390" -#define VIRTIO_SERIAL_S390(obj) \ - OBJECT_CHECK(VirtIOSerialS390, (obj), TYPE_VIRTIO_SERIAL_S390) - -typedef struct VirtIOSerialS390 { - VirtIOS390Device parent_obj; - VirtIOSerial vdev; -} VirtIOSerialS390; - -/* virtio-net-s390 */ - -#define TYPE_VIRTIO_NET_S390 "virtio-net-s390" -#define VIRTIO_NET_S390(obj) \ - OBJECT_CHECK(VirtIONetS390, (obj), TYPE_VIRTIO_NET_S390) - -typedef struct VirtIONetS390 { - VirtIOS390Device parent_obj; - VirtIONet vdev; -} VirtIONetS390; - -/* vhost-scsi-s390 */ - -#ifdef CONFIG_VHOST_SCSI -#define TYPE_VHOST_SCSI_S390 "vhost-scsi-s390" -#define VHOST_SCSI_S390(obj) \ - OBJECT_CHECK(VHostSCSIS390, (obj), TYPE_VHOST_SCSI_S390) - -typedef struct VHostSCSIS390 { - VirtIOS390Device parent_obj; - VHostSCSI vdev; -} VHostSCSIS390; -#endif - -/* virtio-rng-s390 */ - -#define TYPE_VIRTIO_RNG_S390 "virtio-rng-s390" -#define VIRTIO_RNG_S390(obj) \ - OBJECT_CHECK(VirtIORNGS390, (obj), TYPE_VIRTIO_RNG_S390) - -typedef struct VirtIORNGS390 { - VirtIOS390Device parent_obj; - VirtIORNG vdev; -} VirtIORNGS390; - -#endif diff --git a/hw/s390x/s390-virtio-ccw.c b/hw/s390x/s390-virtio-ccw.c index 5a52ff2..586ddbb 100644 --- a/hw/s390x/s390-virtio-ccw.c +++ b/hw/s390x/s390-virtio-ccw.c @@ -235,7 +235,11 @@ static const TypeInfo ccw_machine_info = { }, }; +#define CCW_COMPAT_2_5 \ + HW_COMPAT_2_5 + #define CCW_COMPAT_2_4 \ + CCW_COMPAT_2_5 \ HW_COMPAT_2_4 \ {\ .driver = TYPE_S390_SKEYS,\ @@ -296,10 +300,13 @@ static const TypeInfo ccw_machine_2_4_info = { static void ccw_machine_2_5_class_init(ObjectClass *oc, void *data) { MachineClass *mc = MACHINE_CLASS(oc); + static GlobalProperty compat_props[] = { + CCW_COMPAT_2_5 + { /* end of list */ } + }; - mc->alias = "s390-ccw-virtio"; mc->desc = "VirtIO-ccw based S390 machine v2.5"; - mc->is_default = 1; + mc->compat_props = compat_props; } static const TypeInfo ccw_machine_2_5_info = { @@ -308,11 +315,27 @@ static const TypeInfo ccw_machine_2_5_info = { .class_init = ccw_machine_2_5_class_init, }; +static void ccw_machine_2_6_class_init(ObjectClass *oc, void *data) +{ + MachineClass *mc = MACHINE_CLASS(oc); + + mc->alias = "s390-ccw-virtio"; + mc->desc = "VirtIO-ccw based S390 machine v2.6"; + mc->is_default = 1; +} + +static const TypeInfo ccw_machine_2_6_info = { + .name = MACHINE_TYPE_NAME("s390-ccw-virtio-2.6"), + .parent = TYPE_S390_CCW_MACHINE, + .class_init = ccw_machine_2_6_class_init, +}; + static void ccw_machine_register_types(void) { type_register_static(&ccw_machine_info); type_register_static(&ccw_machine_2_4_info); type_register_static(&ccw_machine_2_5_info); + type_register_static(&ccw_machine_2_6_info); } type_init(ccw_machine_register_types) diff --git a/hw/s390x/s390-virtio.c b/hw/s390x/s390-virtio.c index ae55760..946325f 100644 --- a/hw/s390x/s390-virtio.c +++ b/hw/s390x/s390-virtio.c @@ -35,7 +35,6 @@ #include "exec/address-spaces.h" #include "sysemu/qtest.h" -#include "hw/s390x/s390-virtio-bus.h" #include "hw/s390x/sclp.h" #include "hw/s390x/s390_flic.h" #include "hw/s390x/s390-virtio.h" @@ -61,7 +60,6 @@ #define S390_TOD_CLOCK_VALUE_MISSING 0x00 #define S390_TOD_CLOCK_VALUE_PRESENT 0x01 -static VirtIOS390Bus *s390_bus; static S390CPU **ipi_states; S390CPU *s390_cpu_addr2state(uint16_t cpu_addr) @@ -73,78 +71,6 @@ S390CPU *s390_cpu_addr2state(uint16_t cpu_addr) return ipi_states[cpu_addr]; } -static int s390_virtio_hcall_notify(const uint64_t *args) -{ - uint64_t mem = args[0]; - int r = 0, i; - - if (mem > ram_size) { - VirtIOS390Device *dev = s390_virtio_bus_find_vring(s390_bus, mem, &i); - if (dev) { - /* - * Older kernels will use the virtqueue before setting DRIVER_OK. - * In this case the feature bits are not yet up to date, meaning - * that several funny things can happen, e.g. the guest thinks - * EVENT_IDX is on and QEMU thinks it is off. Let's force a feature - * and status sync. - */ - if (!(dev->vdev->status & VIRTIO_CONFIG_S_DRIVER_OK)) { - s390_virtio_device_update_status(dev); - } - virtio_queue_notify(dev->vdev, i); - } else { - r = -EINVAL; - } - } else { - /* Early printk */ - } - return r; -} - -static int s390_virtio_hcall_reset(const uint64_t *args) -{ - uint64_t mem = args[0]; - VirtIOS390Device *dev; - - dev = s390_virtio_bus_find_mem(s390_bus, mem); - if (dev == NULL) { - return -EINVAL; - } - virtio_reset(dev->vdev); - address_space_stb(&address_space_memory, - dev->dev_offs + VIRTIO_DEV_OFFS_STATUS, 0, - MEMTXATTRS_UNSPECIFIED, NULL); - s390_virtio_device_sync(dev); - s390_virtio_reset_idx(dev); - - return 0; -} - -static int s390_virtio_hcall_set_status(const uint64_t *args) -{ - uint64_t mem = args[0]; - int r = 0; - VirtIOS390Device *dev; - - dev = s390_virtio_bus_find_mem(s390_bus, mem); - if (dev) { - s390_virtio_device_update_status(dev); - } else { - r = -EINVAL; - } - return r; -} - -static void s390_virtio_register_hcalls(void) -{ - s390_register_virtio_hypercall(KVM_S390_VIRTIO_NOTIFY, - s390_virtio_hcall_notify); - s390_register_virtio_hypercall(KVM_S390_VIRTIO_RESET, - s390_virtio_hcall_reset); - s390_register_virtio_hypercall(KVM_S390_VIRTIO_SET_STATUS, - s390_virtio_hcall_set_status); -} - void s390_init_ipl_dev(const char *kernel_filename, const char *kernel_cmdline, const char *initrd_filename, @@ -205,10 +131,7 @@ void s390_create_virtio_net(BusState *bus, const char *name) nd->model = g_strdup("virtio"); } - if (strcmp(nd->model, "virtio")) { - fprintf(stderr, "S390 only supports VirtIO nics\n"); - exit(1); - } + qemu_check_nic_model(nd, "virtio"); dev = qdev_create(bus, name); qdev_set_nic_properties(dev, nd); @@ -261,58 +184,6 @@ int gtod_load(QEMUFile *f, void *opaque, int version_id) return 0; } -/* PC hardware initialisation */ -static void s390_init(MachineState *machine) -{ - ram_addr_t my_ram_size; - void *virtio_region; - hwaddr virtio_region_len; - hwaddr virtio_region_start; - - if (!qtest_enabled()) { - error_printf("WARNING\n" - "The s390-virtio machine (non-ccw) is deprecated.\n" - "It will be removed in 2.6. Please use s390-ccw-virtio\n"); - } - - if (machine->ram_slots) { - error_report("Memory hotplug not supported by the selected machine."); - exit(EXIT_FAILURE); - } - s390_sclp_init(); - my_ram_size = machine->ram_size; - - /* get a BUS */ - s390_bus = s390_virtio_bus_init(&my_ram_size); - s390_init_ipl_dev(machine->kernel_filename, machine->kernel_cmdline, - machine->initrd_filename, ZIPL_FILENAME, false); - s390_flic_init(); - - /* register hypercalls */ - s390_virtio_register_hcalls(); - - /* allocate RAM */ - s390_memory_init(my_ram_size); - - /* clear virtio region */ - virtio_region_len = my_ram_size - ram_size; - virtio_region_start = ram_size; - virtio_region = cpu_physical_memory_map(virtio_region_start, - &virtio_region_len, true); - memset(virtio_region, 0, virtio_region_len); - cpu_physical_memory_unmap(virtio_region, virtio_region_len, 1, - virtio_region_len); - - /* init CPUs */ - s390_init_cpus(machine->cpu_model); - - /* Create VirtIO network adapters */ - s390_create_virtio_net((BusState *)s390_bus, "virtio-net-s390"); - - /* Register savevm handler for guest TOD clock */ - register_savevm(NULL, "todclock", 0, 1, gtod_save, gtod_load, NULL); -} - void s390_nmi(NMIState *n, int cpu_index, Error **errp) { CPUState *cs = qemu_get_cpu(cpu_index); @@ -334,40 +205,3 @@ void s390_machine_reset(void) s390_ipl_prepare_cpu(ipl_cpu); s390_cpu_set_state(CPU_STATE_OPERATING, ipl_cpu); } - -static void s390_machine_class_init(ObjectClass *oc, void *data) -{ - MachineClass *mc = MACHINE_CLASS(oc); - NMIClass *nc = NMI_CLASS(oc); - - mc->alias = "s390"; - mc->desc = "VirtIO based S390 machine (deprecated)"; - mc->init = s390_init; - mc->reset = s390_machine_reset; - mc->block_default_type = IF_VIRTIO; - mc->max_cpus = 255; - mc->no_serial = 1; - mc->no_parallel = 1; - mc->use_virtcon = 1; - mc->no_floppy = 1; - mc->no_cdrom = 1; - mc->no_sdcard = 1; - nc->nmi_monitor_handler = s390_nmi; -} - -static const TypeInfo s390_machine_info = { - .name = TYPE_S390_MACHINE, - .parent = TYPE_MACHINE, - .class_init = s390_machine_class_init, - .interfaces = (InterfaceInfo[]) { - { TYPE_NMI }, - { } - }, -}; - -static void s390_machine_register_types(void) -{ - type_register_static(&s390_machine_info); -} - -type_init(s390_machine_register_types) diff --git a/hw/s390x/virtio-ccw.c b/hw/s390x/virtio-ccw.c index 63da303..95a6c14 100644 --- a/hw/s390x/virtio-ccw.c +++ b/hw/s390x/virtio-ccw.c @@ -1177,7 +1177,8 @@ static void virtio_ccw_notify(DeviceState *d, uint16_t vector) SubchDev *sch = dev->sch; uint64_t indicators; - if (vector >= 128) { + /* queue indicators + secondary indicators */ + if (vector >= VIRTIO_CCW_QUEUE_MAX + 64) { return; } |