int s390_virtio_hypercall(CPUS390XState *env, uint64_t mem, uint64_t hypercall) { int r = 0, i; dprintf("KVM hypercall: %ld\n", hypercall); switch (hypercall) { case KVM_S390_VIRTIO_NOTIFY: if (mem > ram_size) { VirtIOS390Device *dev = s390_virtio_bus_find_vring(s390_bus, mem, &i); if (dev) { virtio_queue_notify(dev->vdev, i); } else { r = -EINVAL; } } else { /* Early printk */ } break; case KVM_S390_VIRTIO_RESET: { VirtIOS390Device *dev; dev = s390_virtio_bus_find_mem(s390_bus, mem); virtio_reset(dev->vdev); stb_phys(dev->dev_offs + VIRTIO_DEV_OFFS_STATUS, 0); s390_virtio_device_sync(dev); s390_virtio_reset_idx(dev); break; } case KVM_S390_VIRTIO_SET_STATUS: { VirtIOS390Device *dev; dev = s390_virtio_bus_find_mem(s390_bus, mem); if (dev) { s390_virtio_device_update_status(dev); } else { r = -EINVAL; } break; } default: r = -EINVAL; break; } 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); stb_phys(&address_space_memory, dev->dev_offs + VIRTIO_DEV_OFFS_STATUS, 0); s390_virtio_device_sync(dev); s390_virtio_reset_idx(dev); return 0; }