qemu with hax to log dma reads & writes jcs.org/2018/11/12/vfio

Merge remote-tracking branch 'remotes/borntraeger/tags/kvm-s390-20140227' into staging

Several features, fixes and cleanups for kvm/s390:

- sclp event facility: cleanup structure. This allows to use
realize/unrealize as well as migration support via vmsd
- reboot: Two fixes that make reboot much more reliable
- ipl: make elf loading more robust
- flic interrupt controller: This allows to migrate floating
interrupts, as well as clear them on reset etc.
- enable async_pf feature of KVM on s390
- several sclp fixes and cleanups
- several sigp fixes and cleanups

* remotes/borntraeger/tags/kvm-s390-20140227: (22 commits)
s390x/ipl: Fix crash of ELF images with arbitrary entry points
s390x/kvm: Rework priv instruction handlers
s390x/kvm: Add missing SIGP CPU RESET order
s390x/kvm: Rework SIGP INITIAL CPU RESET handler
s390x/cpu: Use ioctl to reset state in the kernel
s390-ccw.img: new binary rom to match latest fixes
s390-ccw.img: Fix sporadic errors with ccw boot image - initialize css
s390-ccw.img: Fix sporadic reboot hangs: Initialize next_idx
s390x/event-facility: exploit realize/unrealize
s390x/event-facility: add support for live migration
s390x/event-facility: code restructure
s390x/event-facility: some renaming
s390x/sclp: Fixed setting of condition code register
s390x/sclp: Add missing checks to SCLP handler
s390x/sclp: Fixed the size of sccb and code parameter
s390x/eventfacility: mask out commands
s390x/virtio-hcall: Specification exception for illegal subcodes
s390x/virtio-hcall: Add range check for hypervisor call
s390x/kvm: Fixed bad SIGP SET-ARCHITECTURE handler
s390x/async_pf: Check for apf extension and enable pfault
...

Conflicts:
linux-headers/linux/kvm.h

Signed-off-by: Peter Maydell <peter.maydell@linaro.org>

+757 -214
+1
default-configs/s390x-softmmu.mak
··· 1 1 CONFIG_VIRTIO=y 2 2 CONFIG_SCLPCONSOLE=y 3 + CONFIG_S390_FLIC=$(CONFIG_KVM)
+1
hw/intc/Makefile.objs
··· 25 25 obj-$(CONFIG_XICS) += xics.o 26 26 obj-$(CONFIG_XICS_KVM) += xics_kvm.o 27 27 obj-$(CONFIG_ALLWINNER_A10_PIC) += allwinner-a10-pic.o 28 + obj-$(CONFIG_S390_FLIC) += s390_flic.o
+322
hw/intc/s390_flic.c
··· 1 + /* 2 + * QEMU S390x KVM floating interrupt controller (flic) 3 + * 4 + * Copyright 2014 IBM Corp. 5 + * Author(s): Jens Freimann <jfrei@linux.vnet.ibm.com> 6 + * 7 + * This work is licensed under the terms of the GNU GPL, version 2 or (at 8 + * your option) any later version. See the COPYING file in the top-level 9 + * directory. 10 + */ 11 + 12 + #include <sys/ioctl.h> 13 + #include "qemu/error-report.h" 14 + #include "hw/sysbus.h" 15 + #include "sysemu/kvm.h" 16 + #include "migration/qemu-file.h" 17 + #include "hw/s390x/s390_flic.h" 18 + #include "trace.h" 19 + 20 + #define FLIC_SAVE_INITIAL_SIZE getpagesize() 21 + #define FLIC_FAILED (-1UL) 22 + #define FLIC_SAVEVM_VERSION 1 23 + 24 + void s390_flic_init(void) 25 + { 26 + DeviceState *dev; 27 + int r; 28 + 29 + if (kvm_enabled()) { 30 + dev = qdev_create(NULL, "s390-flic"); 31 + object_property_add_child(qdev_get_machine(), "s390-flic", 32 + OBJECT(dev), NULL); 33 + r = qdev_init(dev); 34 + if (r) { 35 + error_report("flic: couldn't create qdev"); 36 + } 37 + } 38 + } 39 + 40 + /** 41 + * flic_get_all_irqs - store all pending irqs in buffer 42 + * @buf: pointer to buffer which is passed to kernel 43 + * @len: length of buffer 44 + * @flic: pointer to flic device state 45 + * 46 + * Returns: -ENOMEM if buffer is too small, 47 + * -EINVAL if attr.group is invalid, 48 + * -EFAULT if copying to userspace failed, 49 + * on success return number of stored interrupts 50 + */ 51 + static int flic_get_all_irqs(KVMS390FLICState *flic, 52 + void *buf, int len) 53 + { 54 + struct kvm_device_attr attr = { 55 + .group = KVM_DEV_FLIC_GET_ALL_IRQS, 56 + .addr = (uint64_t) buf, 57 + .attr = len, 58 + }; 59 + int rc; 60 + 61 + rc = ioctl(flic->fd, KVM_GET_DEVICE_ATTR, &attr); 62 + 63 + return rc == -1 ? -errno : rc; 64 + } 65 + 66 + static void flic_enable_pfault(KVMS390FLICState *flic) 67 + { 68 + struct kvm_device_attr attr = { 69 + .group = KVM_DEV_FLIC_APF_ENABLE, 70 + }; 71 + int rc; 72 + 73 + rc = ioctl(flic->fd, KVM_SET_DEVICE_ATTR, &attr); 74 + 75 + if (rc) { 76 + fprintf(stderr, "flic: couldn't enable pfault\n"); 77 + } 78 + } 79 + 80 + static void flic_disable_wait_pfault(KVMS390FLICState *flic) 81 + { 82 + struct kvm_device_attr attr = { 83 + .group = KVM_DEV_FLIC_APF_DISABLE_WAIT, 84 + }; 85 + int rc; 86 + 87 + rc = ioctl(flic->fd, KVM_SET_DEVICE_ATTR, &attr); 88 + 89 + if (rc) { 90 + fprintf(stderr, "flic: couldn't disable pfault\n"); 91 + } 92 + } 93 + 94 + /** flic_enqueue_irqs - returns 0 on success 95 + * @buf: pointer to buffer which is passed to kernel 96 + * @len: length of buffer 97 + * @flic: pointer to flic device state 98 + * 99 + * Returns: -EINVAL if attr.group is unknown 100 + */ 101 + static int flic_enqueue_irqs(void *buf, uint64_t len, 102 + KVMS390FLICState *flic) 103 + { 104 + int rc; 105 + struct kvm_device_attr attr = { 106 + .group = KVM_DEV_FLIC_ENQUEUE, 107 + .addr = (uint64_t) buf, 108 + .attr = len, 109 + }; 110 + 111 + rc = ioctl(flic->fd, KVM_SET_DEVICE_ATTR, &attr); 112 + 113 + return rc ? -errno : 0; 114 + } 115 + 116 + /** 117 + * __get_all_irqs - store all pending irqs in buffer 118 + * @flic: pointer to flic device state 119 + * @buf: pointer to pointer to a buffer 120 + * @len: length of buffer 121 + * 122 + * Returns: return value of flic_get_all_irqs 123 + * Note: Retry and increase buffer size until flic_get_all_irqs 124 + * either returns a value >= 0 or a negative error code. 125 + * -ENOMEM is an exception, which means the buffer is too small 126 + * and we should try again. Other negative error codes can be 127 + * -EFAULT and -EINVAL which we ignore at this point 128 + */ 129 + static int __get_all_irqs(KVMS390FLICState *flic, 130 + void **buf, int len) 131 + { 132 + int r; 133 + 134 + do { 135 + /* returns -ENOMEM if buffer is too small and number 136 + * of queued interrupts on success */ 137 + r = flic_get_all_irqs(flic, *buf, len); 138 + if (r >= 0) { 139 + break; 140 + } 141 + len *= 2; 142 + *buf = g_try_realloc(*buf, len); 143 + if (!buf) { 144 + return -ENOMEM; 145 + } 146 + } while (r == -ENOMEM && len <= KVM_S390_FLIC_MAX_BUFFER); 147 + 148 + return r; 149 + } 150 + 151 + /** 152 + * kvm_flic_save - Save pending floating interrupts 153 + * @f: QEMUFile containing migration state 154 + * @opaque: pointer to flic device state 155 + * 156 + * Note: Pass buf and len to kernel. Start with one page and 157 + * increase until buffer is sufficient or maxium size is 158 + * reached 159 + */ 160 + static void kvm_flic_save(QEMUFile *f, void *opaque) 161 + { 162 + KVMS390FLICState *flic = opaque; 163 + int len = FLIC_SAVE_INITIAL_SIZE; 164 + void *buf; 165 + int count; 166 + 167 + flic_disable_wait_pfault((struct KVMS390FLICState *) opaque); 168 + 169 + buf = g_try_malloc0(len); 170 + if (!buf) { 171 + /* Storing FLIC_FAILED into the count field here will cause the 172 + * target system to fail when attempting to load irqs from the 173 + * migration state */ 174 + error_report("flic: couldn't allocate memory"); 175 + qemu_put_be64(f, FLIC_FAILED); 176 + return; 177 + } 178 + 179 + count = __get_all_irqs(flic, &buf, len); 180 + if (count < 0) { 181 + error_report("flic: couldn't retrieve irqs from kernel, rc %d", 182 + count); 183 + /* Storing FLIC_FAILED into the count field here will cause the 184 + * target system to fail when attempting to load irqs from the 185 + * migration state */ 186 + qemu_put_be64(f, FLIC_FAILED); 187 + } else { 188 + qemu_put_be64(f, count); 189 + qemu_put_buffer(f, (uint8_t *) buf, 190 + count * sizeof(struct kvm_s390_irq)); 191 + } 192 + g_free(buf); 193 + } 194 + 195 + /** 196 + * kvm_flic_load - Load pending floating interrupts 197 + * @f: QEMUFile containing migration state 198 + * @opaque: pointer to flic device state 199 + * @version_id: version id for migration 200 + * 201 + * Returns: value of flic_enqueue_irqs, -EINVAL on error 202 + * Note: Do nothing when no interrupts where stored 203 + * in QEMUFile 204 + */ 205 + static int kvm_flic_load(QEMUFile *f, void *opaque, int version_id) 206 + { 207 + uint64_t len = 0; 208 + uint64_t count = 0; 209 + void *buf = NULL; 210 + int r = 0; 211 + 212 + if (version_id != FLIC_SAVEVM_VERSION) { 213 + r = -EINVAL; 214 + goto out; 215 + } 216 + 217 + flic_enable_pfault((struct KVMS390FLICState *) opaque); 218 + 219 + count = qemu_get_be64(f); 220 + len = count * sizeof(struct kvm_s390_irq); 221 + if (count == FLIC_FAILED) { 222 + r = -EINVAL; 223 + goto out; 224 + } 225 + if (count == 0) { 226 + r = 0; 227 + goto out; 228 + } 229 + buf = g_try_malloc0(len); 230 + if (!buf) { 231 + r = -ENOMEM; 232 + goto out; 233 + } 234 + 235 + if (qemu_get_buffer(f, (uint8_t *) buf, len) != len) { 236 + r = -EINVAL; 237 + goto out_free; 238 + } 239 + r = flic_enqueue_irqs(buf, len, (struct KVMS390FLICState *) opaque); 240 + 241 + out_free: 242 + g_free(buf); 243 + out: 244 + return r; 245 + } 246 + 247 + static void kvm_s390_flic_realize(DeviceState *dev, Error **errp) 248 + { 249 + KVMS390FLICState *flic_state = KVM_S390_FLIC(dev); 250 + struct kvm_create_device cd = {0}; 251 + int ret; 252 + 253 + flic_state->fd = -1; 254 + if (!kvm_check_extension(kvm_state, KVM_CAP_DEVICE_CTRL)) { 255 + trace_flic_no_device_api(errno); 256 + return; 257 + } 258 + 259 + cd.type = KVM_DEV_TYPE_FLIC; 260 + ret = kvm_vm_ioctl(kvm_state, KVM_CREATE_DEVICE, &cd); 261 + if (ret < 0) { 262 + trace_flic_create_device(errno); 263 + return; 264 + } 265 + flic_state->fd = cd.fd; 266 + 267 + /* Register savevm handler for floating interrupts */ 268 + register_savevm(NULL, "s390-flic", 0, 1, kvm_flic_save, 269 + kvm_flic_load, (void *) flic_state); 270 + } 271 + 272 + static void kvm_s390_flic_unrealize(DeviceState *dev, Error **errp) 273 + { 274 + KVMS390FLICState *flic_state = KVM_S390_FLIC(dev); 275 + 276 + unregister_savevm(DEVICE(flic_state), "s390-flic", flic_state); 277 + } 278 + 279 + static void kvm_s390_flic_reset(DeviceState *dev) 280 + { 281 + KVMS390FLICState *flic = KVM_S390_FLIC(dev); 282 + struct kvm_device_attr attr = { 283 + .group = KVM_DEV_FLIC_CLEAR_IRQS, 284 + }; 285 + int rc = 0; 286 + 287 + if (flic->fd == -1) { 288 + return; 289 + } 290 + 291 + flic_disable_wait_pfault(flic); 292 + 293 + rc = ioctl(flic->fd, KVM_SET_DEVICE_ATTR, &attr); 294 + if (rc) { 295 + trace_flic_reset_failed(errno); 296 + } 297 + 298 + flic_enable_pfault(flic); 299 + } 300 + 301 + static void kvm_s390_flic_class_init(ObjectClass *oc, void *data) 302 + { 303 + DeviceClass *dc = DEVICE_CLASS(oc); 304 + 305 + dc->realize = kvm_s390_flic_realize; 306 + dc->unrealize = kvm_s390_flic_unrealize; 307 + dc->reset = kvm_s390_flic_reset; 308 + } 309 + 310 + static const TypeInfo kvm_s390_flic_info = { 311 + .name = TYPE_KVM_S390_FLIC, 312 + .parent = TYPE_SYS_BUS_DEVICE, 313 + .instance_size = sizeof(KVMS390FLICState), 314 + .class_init = kvm_s390_flic_class_init, 315 + }; 316 + 317 + static void kvm_s390_flic_register_types(void) 318 + { 319 + type_register_static(&kvm_s390_flic_info); 320 + } 321 + 322 + type_init(kvm_s390_flic_register_types)
+56 -37
hw/s390x/event-facility.c
··· 21 21 #include "hw/s390x/sclp.h" 22 22 #include "hw/s390x/event-facility.h" 23 23 24 - typedef struct EventTypesBus { 24 + typedef struct SCLPEventsBus { 25 25 BusState qbus; 26 - } EventTypesBus; 26 + } SCLPEventsBus; 27 27 28 28 struct SCLPEventFacility { 29 - EventTypesBus sbus; 30 - DeviceState *qdev; 29 + SysBusDevice parent_obj; 30 + SCLPEventsBus sbus; 31 31 /* guest' receive mask */ 32 32 unsigned int receive_mask; 33 33 }; ··· 291 291 { 292 292 } 293 293 294 - static const TypeInfo s390_sclp_events_bus_info = { 294 + static const TypeInfo sclp_events_bus_info = { 295 295 .name = TYPE_SCLP_EVENTS_BUS, 296 296 .parent = TYPE_BUS, 297 297 .class_init = sclp_events_bus_class_init, ··· 299 299 300 300 static void command_handler(SCLPEventFacility *ef, SCCB *sccb, uint64_t code) 301 301 { 302 - switch (code) { 302 + switch (code & SCLP_CMD_CODE_MASK) { 303 303 case SCLP_CMD_READ_EVENT_DATA: 304 304 read_event_data(ef, sccb); 305 305 break; ··· 315 315 } 316 316 } 317 317 318 - static int init_event_facility(S390SCLPDevice *sdev) 318 + static const VMStateDescription vmstate_event_facility = { 319 + .name = "vmstate-event-facility", 320 + .version_id = 0, 321 + .minimum_version_id = 0, 322 + .minimum_version_id_old = 0, 323 + .fields = (VMStateField[]) { 324 + VMSTATE_UINT32(receive_mask, SCLPEventFacility), 325 + VMSTATE_END_OF_LIST() 326 + } 327 + }; 328 + 329 + static int init_event_facility(SCLPEventFacility *event_facility) 319 330 { 320 - SCLPEventFacility *event_facility; 331 + DeviceState *sdev = DEVICE(event_facility); 321 332 DeviceState *quiesce; 322 333 323 - event_facility = g_malloc0(sizeof(SCLPEventFacility)); 324 - sdev->ef = event_facility; 325 - sdev->sclp_command_handler = command_handler; 326 - sdev->event_pending = event_pending; 327 - 328 - /* Spawn a new sclp-events facility */ 334 + /* Spawn a new bus for SCLP events */ 329 335 qbus_create_inplace(&event_facility->sbus, sizeof(event_facility->sbus), 330 - TYPE_SCLP_EVENTS_BUS, DEVICE(sdev), NULL); 336 + TYPE_SCLP_EVENTS_BUS, sdev, NULL); 331 337 event_facility->sbus.qbus.allow_hotplug = 0; 332 - event_facility->qdev = (DeviceState *) sdev; 333 338 334 339 quiesce = qdev_create(&event_facility->sbus.qbus, "sclpquiesce"); 335 340 if (!quiesce) { ··· 346 351 347 352 static void reset_event_facility(DeviceState *dev) 348 353 { 349 - S390SCLPDevice *sdev = SCLP_S390_DEVICE(dev); 354 + SCLPEventFacility *sdev = EVENT_FACILITY(dev); 350 355 351 - sdev->ef->receive_mask = 0; 356 + sdev->receive_mask = 0; 352 357 } 353 358 354 359 static void init_event_facility_class(ObjectClass *klass, void *data) 355 360 { 356 - DeviceClass *dc = DEVICE_CLASS(klass); 357 - S390SCLPDeviceClass *k = SCLP_S390_DEVICE_CLASS(klass); 361 + SysBusDeviceClass *sbdc = SYS_BUS_DEVICE_CLASS(klass); 362 + DeviceClass *dc = DEVICE_CLASS(sbdc); 363 + SCLPEventFacilityClass *k = EVENT_FACILITY_CLASS(dc); 358 364 359 365 dc->reset = reset_event_facility; 366 + dc->vmsd = &vmstate_event_facility; 360 367 k->init = init_event_facility; 368 + k->command_handler = command_handler; 369 + k->event_pending = event_pending; 361 370 } 362 371 363 - static const TypeInfo s390_sclp_event_facility_info = { 364 - .name = "s390-sclp-event-facility", 365 - .parent = TYPE_DEVICE_S390_SCLP, 366 - .instance_size = sizeof(S390SCLPDevice), 372 + static const TypeInfo sclp_event_facility_info = { 373 + .name = TYPE_SCLP_EVENT_FACILITY, 374 + .parent = TYPE_SYS_BUS_DEVICE, 375 + .instance_size = sizeof(SCLPEventFacility), 367 376 .class_init = init_event_facility_class, 377 + .class_size = sizeof(SCLPEventFacilityClass), 368 378 }; 369 379 370 - static int event_qdev_init(DeviceState *qdev) 380 + static void event_realize(DeviceState *qdev, Error **errp) 371 381 { 372 - SCLPEvent *event = DO_UPCAST(SCLPEvent, qdev, qdev); 382 + SCLPEvent *event = SCLP_EVENT(qdev); 373 383 SCLPEventClass *child = SCLP_EVENT_GET_CLASS(event); 374 384 375 - return child->init(event); 385 + if (child->init) { 386 + int rc = child->init(event); 387 + if (rc < 0) { 388 + error_setg(errp, "SCLP event initialization failed."); 389 + return; 390 + } 391 + } 376 392 } 377 393 378 - static int event_qdev_exit(DeviceState *qdev) 394 + static void event_unrealize(DeviceState *qdev, Error **errp) 379 395 { 380 - SCLPEvent *event = DO_UPCAST(SCLPEvent, qdev, qdev); 396 + SCLPEvent *event = SCLP_EVENT(qdev); 381 397 SCLPEventClass *child = SCLP_EVENT_GET_CLASS(event); 382 398 if (child->exit) { 383 - child->exit(event); 399 + int rc = child->exit(event); 400 + if (rc < 0) { 401 + error_setg(errp, "SCLP event exit failed."); 402 + return; 403 + } 384 404 } 385 - return 0; 386 405 } 387 406 388 407 static void event_class_init(ObjectClass *klass, void *data) ··· 391 410 392 411 dc->bus_type = TYPE_SCLP_EVENTS_BUS; 393 412 dc->unplug = qdev_simple_unplug_cb; 394 - dc->init = event_qdev_init; 395 - dc->exit = event_qdev_exit; 413 + dc->realize = event_realize; 414 + dc->unrealize = event_unrealize; 396 415 } 397 416 398 - static const TypeInfo s390_sclp_event_type_info = { 417 + static const TypeInfo sclp_event_type_info = { 399 418 .name = TYPE_SCLP_EVENT, 400 419 .parent = TYPE_DEVICE, 401 420 .instance_size = sizeof(SCLPEvent), ··· 406 425 407 426 static void register_types(void) 408 427 { 409 - type_register_static(&s390_sclp_events_bus_info); 410 - type_register_static(&s390_sclp_event_facility_info); 411 - type_register_static(&s390_sclp_event_type_info); 428 + type_register_static(&sclp_events_bus_info); 429 + type_register_static(&sclp_event_facility_info); 430 + type_register_static(&sclp_event_type_info); 412 431 } 413 432 414 433 type_init(register_types)
+13 -8
hw/s390x/ipl.c
··· 95 95 } 96 96 return 0; 97 97 } else { 98 - kernel_size = load_elf(ipl->kernel, NULL, NULL, NULL, NULL, 98 + uint64_t pentry = KERN_IMAGE_START; 99 + kernel_size = load_elf(ipl->kernel, NULL, NULL, &pentry, NULL, 99 100 NULL, 1, ELF_MACHINE, 0); 100 101 if (kernel_size == -1) { 101 102 kernel_size = load_image_targphys(ipl->kernel, 0, ram_size); ··· 104 105 fprintf(stderr, "could not load kernel '%s'\n", ipl->kernel); 105 106 return -1; 106 107 } 107 - /* we have to overwrite values in the kernel image, which are "rom" */ 108 - strcpy(rom_ptr(KERN_PARM_AREA), ipl->cmdline); 109 - 110 108 /* 111 - * we can not rely on the ELF entry point, since up to 3.2 this 112 - * value was 0x800 (the SALIPL loader) and it wont work. For 113 - * all (Linux) cases 0x10000 (KERN_IMAGE_START) should be fine. 109 + * Is it a Linux kernel (starting at 0x10000)? If yes, we fill in the 110 + * kernel parameters here as well. Note: For old kernels (up to 3.2) 111 + * we can not rely on the ELF entry point - it was 0x800 (the SALIPL 112 + * loader) and it won't work. For this case we force it to 0x10000, too. 114 113 */ 115 - ipl->start_addr = KERN_IMAGE_START; 114 + if (pentry == KERN_IMAGE_START || pentry == 0x800) { 115 + ipl->start_addr = KERN_IMAGE_START; 116 + /* Overwrite parameters in the kernel image, which are "rom" */ 117 + strcpy(rom_ptr(KERN_PARM_AREA), ipl->cmdline); 118 + } else { 119 + ipl->start_addr = pentry; 120 + } 116 121 } 117 122 if (ipl->initrd) { 118 123 ram_addr_t initrd_offset;
+7 -1
hw/s390x/s390-virtio-ccw.c
··· 13 13 #include "exec/address-spaces.h" 14 14 #include "s390-virtio.h" 15 15 #include "hw/s390x/sclp.h" 16 + #include "hw/s390x/s390_flic.h" 16 17 #include "ioinst.h" 17 18 #include "css.h" 18 19 #include "virtio-ccw.h" 19 20 20 21 void io_subsystem_reset(void) 21 22 { 22 - DeviceState *css, *sclp; 23 + DeviceState *css, *sclp, *flic; 23 24 24 25 css = DEVICE(object_resolve_path_type("", "virtual-css-bridge", NULL)); 25 26 if (css) { ··· 29 30 "s390-sclp-event-facility", NULL)); 30 31 if (sclp) { 31 32 qdev_reset_all(sclp); 33 + } 34 + flic = DEVICE(object_resolve_path_type("", "s390-flic", NULL)); 35 + if (flic) { 36 + qdev_reset_all(flic); 32 37 } 33 38 } 34 39 ··· 99 104 s390_sclp_init(); 100 105 s390_init_ipl_dev(args->kernel_filename, args->kernel_cmdline, 101 106 args->initrd_filename, "s390-ccw.img"); 107 + s390_flic_init(); 102 108 103 109 /* register hypercalls */ 104 110 virtio_ccw_register_hcalls();
+8 -4
hw/s390x/s390-virtio-hcall.c
··· 26 26 27 27 int s390_virtio_hypercall(CPUS390XState *env) 28 28 { 29 - s390_virtio_fn fn = s390_diag500_table[env->regs[1]]; 29 + s390_virtio_fn fn; 30 30 31 - if (!fn) { 32 - return -EINVAL; 31 + if (env->regs[1] < MAX_DIAG_SUBCODES) { 32 + fn = s390_diag500_table[env->regs[1]]; 33 + if (fn) { 34 + env->regs[2] = fn(&env->regs[2]); 35 + return 0; 36 + } 33 37 } 34 38 35 - return fn(&env->regs[2]); 39 + return -EINVAL; 36 40 }
+2
hw/s390x/s390-virtio.c
··· 36 36 37 37 #include "hw/s390x/s390-virtio-bus.h" 38 38 #include "hw/s390x/sclp.h" 39 + #include "hw/s390x/s390_flic.h" 39 40 #include "hw/s390x/s390-virtio.h" 40 41 41 42 //#define DEBUG_S390 ··· 251 252 s390_sclp_init(); 252 253 s390_init_ipl_dev(args->kernel_filename, args->kernel_cmdline, 253 254 args->initrd_filename, ZIPL_FILENAME); 255 + s390_flic_init(); 254 256 255 257 /* register hypercalls */ 256 258 s390_virtio_register_hcalls();
+20 -49
hw/s390x/sclp.c
··· 18 18 #include "sysemu/sysemu.h" 19 19 20 20 #include "hw/s390x/sclp.h" 21 + #include "hw/s390x/event-facility.h" 21 22 22 - static inline S390SCLPDevice *get_event_facility(void) 23 + static inline SCLPEventFacility *get_event_facility(void) 23 24 { 24 25 ObjectProperty *op = object_property_find(qdev_get_machine(), 25 - "s390-sclp-event-facility", 26 + TYPE_SCLP_EVENT_FACILITY, 26 27 NULL); 27 28 assert(op); 28 29 return op->opaque; ··· 89 90 sccb->h.response_code = cpu_to_be16(SCLP_RC_NORMAL_READ_COMPLETION); 90 91 } 91 92 92 - static void sclp_execute(SCCB *sccb, uint64_t code) 93 + static void sclp_execute(SCCB *sccb, uint32_t code) 93 94 { 94 - S390SCLPDevice *sdev = get_event_facility(); 95 + SCLPEventFacility *ef = get_event_facility(); 96 + SCLPEventFacilityClass *efc = EVENT_FACILITY_GET_CLASS(ef); 95 97 96 98 switch (code & SCLP_CMD_CODE_MASK) { 97 99 case SCLP_CMDW_READ_SCP_INFO: ··· 102 104 sclp_read_cpu_info(sccb); 103 105 break; 104 106 default: 105 - sdev->sclp_command_handler(sdev->ef, sccb, code); 107 + efc->command_handler(ef, sccb, code); 106 108 break; 107 109 } 108 110 } 109 111 110 - int sclp_service_call(uint32_t sccb, uint64_t code) 112 + int sclp_service_call(CPUS390XState *env, uint64_t sccb, uint32_t code) 111 113 { 112 114 int r = 0; 113 115 SCCB work_sccb; ··· 115 117 hwaddr sccb_len = sizeof(SCCB); 116 118 117 119 /* first some basic checks on program checks */ 120 + if (env->psw.mask & PSW_MASK_PSTATE) { 121 + r = -PGM_PRIVILEGED; 122 + goto out; 123 + } 118 124 if (cpu_physical_memory_is_io(sccb)) { 119 125 r = -PGM_ADDRESSING; 120 126 goto out; 121 127 } 122 - if (sccb & ~0x7ffffff8ul) { 128 + if ((sccb & ~0x1fffUL) == 0 || (sccb & ~0x1fffUL) == env->psa 129 + || (sccb & ~0x7ffffff8UL) != 0) { 123 130 r = -PGM_SPECIFICATION; 124 131 goto out; 125 132 } ··· 151 158 152 159 void sclp_service_interrupt(uint32_t sccb) 153 160 { 154 - S390SCLPDevice *sdev = get_event_facility(); 161 + SCLPEventFacility *ef = get_event_facility(); 162 + SCLPEventFacilityClass *efc = EVENT_FACILITY_GET_CLASS(ef); 163 + 155 164 uint32_t param = sccb & ~3; 156 165 157 166 /* Indicate whether an event is still pending */ 158 - param |= sdev->event_pending(sdev->ef) ? 1 : 0; 167 + param |= efc->event_pending(ef) ? 1 : 0; 159 168 160 169 if (!param) { 161 170 /* No need to send an interrupt, there's nothing to be notified about */ ··· 168 177 169 178 void s390_sclp_init(void) 170 179 { 171 - DeviceState *dev = qdev_create(NULL, "s390-sclp-event-facility"); 180 + DeviceState *dev = qdev_create(NULL, TYPE_SCLP_EVENT_FACILITY); 172 181 173 - object_property_add_child(qdev_get_machine(), "s390-sclp-event-facility", 182 + object_property_add_child(qdev_get_machine(), TYPE_SCLP_EVENT_FACILITY, 174 183 OBJECT(dev), NULL); 175 184 qdev_init_nofail(dev); 176 185 } 177 - 178 - static int s390_sclp_dev_init(SysBusDevice *dev) 179 - { 180 - int r; 181 - S390SCLPDevice *sdev = (S390SCLPDevice *)dev; 182 - S390SCLPDeviceClass *sclp = SCLP_S390_DEVICE_GET_CLASS(dev); 183 - 184 - r = sclp->init(sdev); 185 - if (!r) { 186 - assert(sdev->event_pending); 187 - assert(sdev->sclp_command_handler); 188 - } 189 - 190 - return r; 191 - } 192 - 193 - static void s390_sclp_device_class_init(ObjectClass *klass, void *data) 194 - { 195 - SysBusDeviceClass *dc = SYS_BUS_DEVICE_CLASS(klass); 196 - 197 - dc->init = s390_sclp_dev_init; 198 - } 199 - 200 - static const TypeInfo s390_sclp_device_info = { 201 - .name = TYPE_DEVICE_S390_SCLP, 202 - .parent = TYPE_SYS_BUS_DEVICE, 203 - .instance_size = sizeof(S390SCLPDevice), 204 - .class_init = s390_sclp_device_class_init, 205 - .class_size = sizeof(S390SCLPDeviceClass), 206 - .abstract = true, 207 - }; 208 - 209 - static void s390_sclp_register_types(void) 210 - { 211 - type_register_static(&s390_sclp_device_info); 212 - } 213 - 214 - type_init(s390_sclp_register_types)
+19
include/hw/s390x/event-facility.h
··· 176 176 bool (*can_handle_event)(uint8_t type); 177 177 } SCLPEventClass; 178 178 179 + #define TYPE_SCLP_EVENT_FACILITY "s390-sclp-event-facility" 180 + #define EVENT_FACILITY(obj) \ 181 + OBJECT_CHECK(SCLPEventFacility, (obj), TYPE_SCLP_EVENT_FACILITY) 182 + #define EVENT_FACILITY_CLASS(klass) \ 183 + OBJECT_CLASS_CHECK(SCLPEventFacilityClass, (klass), \ 184 + TYPE_SCLP_EVENT_FACILITY) 185 + #define EVENT_FACILITY_GET_CLASS(obj) \ 186 + OBJECT_GET_CLASS(SCLPEventFacilityClass, (obj), \ 187 + TYPE_SCLP_EVENT_FACILITY) 188 + 189 + typedef struct SCLPEventFacility SCLPEventFacility; 190 + 191 + typedef struct SCLPEventFacilityClass { 192 + DeviceClass parent_class; 193 + int (*init)(SCLPEventFacility *ef); 194 + void (*command_handler)(SCLPEventFacility *ef, SCCB *sccb, uint64_t code); 195 + bool (*event_pending)(SCLPEventFacility *ef); 196 + } SCLPEventFacilityClass; 197 + 179 198 #endif
+33
include/hw/s390x/s390_flic.h
··· 1 + /* 2 + * QEMU S390x KVM floating interrupt controller (flic) 3 + * 4 + * Copyright 2014 IBM Corp. 5 + * Author(s): Jens Freimann <jfrei@linux.vnet.ibm.com> 6 + * 7 + * This work is licensed under the terms of the GNU GPL, version 2 or (at 8 + * your option) any later version. See the COPYING file in the top-level 9 + * directory. 10 + */ 11 + 12 + #ifndef __KVM_S390_FLIC_H 13 + #define __KVM_S390_FLIC_H 14 + 15 + #include "hw/sysbus.h" 16 + 17 + #define TYPE_KVM_S390_FLIC "s390-flic" 18 + #define KVM_S390_FLIC(obj) \ 19 + OBJECT_CHECK(KVMS390FLICState, (obj), TYPE_KVM_S390_FLIC) 20 + 21 + typedef struct KVMS390FLICState { 22 + SysBusDevice parent_obj; 23 + 24 + uint32_t fd; 25 + } KVMS390FLICState; 26 + 27 + #ifdef CONFIG_KVM 28 + void s390_flic_init(void); 29 + #else 30 + static inline void s390_flic_init(void) { } 31 + #endif 32 + 33 + #endif /* __KVM_S390_FLIC_H */
-24
include/hw/s390x/sclp.h
··· 161 161 return be16_to_cpu(sccb->h.length) - sizeof(sccb->h); 162 162 } 163 163 164 - #define TYPE_DEVICE_S390_SCLP "s390-sclp-device" 165 - #define SCLP_S390_DEVICE(obj) \ 166 - OBJECT_CHECK(S390SCLPDevice, (obj), TYPE_DEVICE_S390_SCLP) 167 - #define SCLP_S390_DEVICE_CLASS(klass) \ 168 - OBJECT_CLASS_CHECK(S390SCLPDeviceClass, (klass), \ 169 - TYPE_DEVICE_S390_SCLP) 170 - #define SCLP_S390_DEVICE_GET_CLASS(obj) \ 171 - OBJECT_GET_CLASS(S390SCLPDeviceClass, (obj), \ 172 - TYPE_DEVICE_S390_SCLP) 173 - 174 - typedef struct SCLPEventFacility SCLPEventFacility; 175 - 176 - typedef struct S390SCLPDevice { 177 - SysBusDevice busdev; 178 - SCLPEventFacility *ef; 179 - void (*sclp_command_handler)(SCLPEventFacility *ef, SCCB *sccb, 180 - uint64_t code); 181 - bool (*event_pending)(SCLPEventFacility *ef); 182 - } S390SCLPDevice; 183 - 184 - typedef struct S390SCLPDeviceClass { 185 - DeviceClass qdev; 186 - int (*init)(S390SCLPDevice *sdev); 187 - } S390SCLPDeviceClass; 188 164 189 165 void s390_sclp_init(void); 190 166 void sclp_service_interrupt(uint32_t sccb);
+19
linux-headers/asm-s390/kvm.h
··· 16 16 17 17 #define __KVM_S390 18 18 19 + /* Device control API: s390-specific devices */ 20 + #define KVM_DEV_FLIC_GET_ALL_IRQS 1 21 + #define KVM_DEV_FLIC_ENQUEUE 2 22 + #define KVM_DEV_FLIC_CLEAR_IRQS 3 23 + #define KVM_DEV_FLIC_APF_ENABLE 4 24 + #define KVM_DEV_FLIC_APF_DISABLE_WAIT 5 25 + /* 26 + * We can have up to 4*64k pending subchannels + 8 adapter interrupts, 27 + * as well as up to ASYNC_PF_PER_VCPU*KVM_MAX_VCPUS pfault done interrupts. 28 + * There are also sclp and machine checks. This gives us 29 + * sizeof(kvm_s390_irq)*(4*65536+8+64*64+1+1) = 72 * 266250 = 19170000 30 + * Lets round up to 8192 pages. 31 + */ 32 + #define KVM_S390_MAX_FLOAT_IRQS 266250 33 + #define KVM_S390_FLIC_MAX_BUFFER 0x2000000 34 + 19 35 /* for KVM_GET_REGS and KVM_SET_REGS */ 20 36 struct kvm_regs { 21 37 /* general purpose regs for s390 */ ··· 57 73 #define KVM_REG_S390_EPOCHDIFF (KVM_REG_S390 | KVM_REG_SIZE_U64 | 0x2) 58 74 #define KVM_REG_S390_CPU_TIMER (KVM_REG_S390 | KVM_REG_SIZE_U64 | 0x3) 59 75 #define KVM_REG_S390_CLOCK_COMP (KVM_REG_S390 | KVM_REG_SIZE_U64 | 0x4) 76 + #define KVM_REG_S390_PFTOKEN (KVM_REG_S390 | KVM_REG_SIZE_U64 | 0x5) 77 + #define KVM_REG_S390_PFCOMPARE (KVM_REG_S390 | KVM_REG_SIZE_U64 | 0x6) 78 + #define KVM_REG_S390_PFSELECT (KVM_REG_S390 | KVM_REG_SIZE_U64 | 0x7) 60 79 #endif
+66
linux-headers/linux/kvm.h
··· 413 413 #define KVM_S390_PROGRAM_INT 0xfffe0001u 414 414 #define KVM_S390_SIGP_SET_PREFIX 0xfffe0002u 415 415 #define KVM_S390_RESTART 0xfffe0003u 416 + #define KVM_S390_INT_PFAULT_INIT 0xfffe0004u 417 + #define KVM_S390_INT_PFAULT_DONE 0xfffe0005u 416 418 #define KVM_S390_MCHK 0xfffe1000u 417 419 #define KVM_S390_INT_VIRTIO 0xffff2603u 418 420 #define KVM_S390_INT_SERVICE 0xffff2401u ··· 432 434 __u32 type; 433 435 __u32 parm; 434 436 __u64 parm64; 437 + }; 438 + 439 + struct kvm_s390_io_info { 440 + __u16 subchannel_id; 441 + __u16 subchannel_nr; 442 + __u32 io_int_parm; 443 + __u32 io_int_word; 444 + }; 445 + 446 + struct kvm_s390_ext_info { 447 + __u32 ext_params; 448 + __u32 pad; 449 + __u64 ext_params2; 450 + }; 451 + 452 + struct kvm_s390_pgm_info { 453 + __u64 trans_exc_code; 454 + __u64 mon_code; 455 + __u64 per_address; 456 + __u32 data_exc_code; 457 + __u16 code; 458 + __u16 mon_class_nr; 459 + __u8 per_code; 460 + __u8 per_atmid; 461 + __u8 exc_access_id; 462 + __u8 per_access_id; 463 + __u8 op_access_id; 464 + __u8 pad[3]; 465 + }; 466 + 467 + struct kvm_s390_prefix_info { 468 + __u32 address; 469 + }; 470 + 471 + struct kvm_s390_extcall_info { 472 + __u16 code; 473 + }; 474 + 475 + struct kvm_s390_emerg_info { 476 + __u16 code; 477 + }; 478 + 479 + struct kvm_s390_mchk_info { 480 + __u64 cr14; 481 + __u64 mcic; 482 + __u64 failing_storage_address; 483 + __u32 ext_damage_code; 484 + __u32 pad; 485 + __u8 fixed_logout[16]; 486 + }; 487 + 488 + struct kvm_s390_irq { 489 + __u64 type; 490 + union { 491 + struct kvm_s390_io_info io; 492 + struct kvm_s390_ext_info ext; 493 + struct kvm_s390_pgm_info pgm; 494 + struct kvm_s390_emerg_info emerg; 495 + struct kvm_s390_extcall_info extcall; 496 + struct kvm_s390_prefix_info prefix; 497 + struct kvm_s390_mchk_info mchk; 498 + char reserved[64]; 499 + } u; 435 500 }; 436 501 437 502 /* for KVM_SET_GUEST_DEBUG */ ··· 855 920 #define KVM_DEV_VFIO_GROUP_ADD 1 856 921 #define KVM_DEV_VFIO_GROUP_DEL 2 857 922 #define KVM_DEV_TYPE_ARM_VGIC_V2 5 923 + #define KVM_DEV_TYPE_FLIC 6 858 924 859 925 /* 860 926 * ioctls for VM fds
pc-bios/s390-ccw.img

This is a binary file and will not be displayed.

+1 -2
pc-bios/s390-ccw/main.c
··· 10 10 11 11 #include "s390-ccw.h" 12 12 13 - struct subchannel_id blk_schid; 14 13 char stack[PAGE_SIZE * 8] __attribute__((__aligned__(PAGE_SIZE))); 15 14 uint64_t boot_value; 16 15 ··· 23 22 24 23 static void virtio_setup(uint64_t dev_info) 25 24 { 25 + struct subchannel_id blk_schid = { .one = 1 }; 26 26 struct schib schib; 27 27 int i; 28 28 int r; 29 29 bool found = false; 30 30 bool check_devno = false; 31 31 uint16_t dev_no = -1; 32 - blk_schid.one = 1; 33 32 34 33 if (dev_info != -1) { 35 34 check_devno = true;
+1
pc-bios/s390-ccw/virtio.c
··· 124 124 vr->used->flags = VRING_USED_F_NO_NOTIFY; 125 125 vr->used->idx = 0; 126 126 vr->used_idx = 0; 127 + vr->next_idx = 0; 127 128 128 129 debug_print_addr("init vr", vr); 129 130 }
+15
target-s390x/cpu.c
··· 83 83 S390CPUClass *scc = S390_CPU_GET_CLASS(cpu); 84 84 CPUS390XState *env = &cpu->env; 85 85 86 + env->pfault_token = -1UL; 86 87 s390_del_running_cpu(cpu); 87 88 scc->parent_reset(s); 88 89 #if !defined(CONFIG_USER_ONLY) ··· 105 106 /* architectured initial values for CR 0 and 14 */ 106 107 env->cregs[0] = CR0_RESET; 107 108 env->cregs[14] = CR14_RESET; 109 + 110 + env->pfault_token = -1UL; 111 + 112 + #if defined(CONFIG_KVM) 113 + /* Reset state inside the kernel that we cannot access yet from QEMU. */ 114 + if (kvm_enabled()) { 115 + if (kvm_vcpu_ioctl(s, KVM_S390_INITIAL_RESET, NULL)) { 116 + perror("Initial CPU reset failed"); 117 + } 118 + } 119 + #endif 108 120 } 109 121 110 122 /* CPUClass:reset() */ ··· 123 135 /* architectured initial values for CR 0 and 14 */ 124 136 env->cregs[0] = CR0_RESET; 125 137 env->cregs[14] = CR14_RESET; 138 + 139 + env->pfault_token = -1UL; 140 + 126 141 /* set halted to 1 to make sure we can add the cpu in 127 142 * s390_ipl_cpu code, where CPUState::halted is set back to 0 128 143 * after incrementing the cpu counter */
+5 -1
target-s390x/cpu.h
··· 121 121 uint64_t cputm; 122 122 uint32_t todpr; 123 123 124 + uint64_t pfault_token; 125 + uint64_t pfault_compare; 126 + uint64_t pfault_select; 127 + 124 128 CPU_COMMON 125 129 126 130 /* reset does memset(0) up to here */ ··· 959 963 void load_psw(CPUS390XState *env, uint64_t mask, uint64_t addr); 960 964 int mmu_translate(CPUS390XState *env, target_ulong vaddr, int rw, uint64_t asc, 961 965 target_ulong *raddr, int *flags); 962 - int sclp_service_call(uint32_t sccb, uint64_t code); 966 + int sclp_service_call(CPUS390XState *env, uint64_t sccb, uint32_t code); 963 967 uint32_t calc_cc(CPUS390XState *env, uint32_t cc_op, uint64_t src, uint64_t dst, 964 968 uint64_t vr); 965 969
+162 -87
target-s390x/kvm.c
··· 53 53 #define IPA0_B9 0xb900 54 54 #define IPA0_EB 0xeb00 55 55 56 - #define PRIV_SCLP_CALL 0x20 57 - #define PRIV_CSCH 0x30 58 - #define PRIV_HSCH 0x31 59 - #define PRIV_MSCH 0x32 60 - #define PRIV_SSCH 0x33 61 - #define PRIV_STSCH 0x34 62 - #define PRIV_TSCH 0x35 63 - #define PRIV_TPI 0x36 64 - #define PRIV_SAL 0x37 65 - #define PRIV_RSCH 0x38 66 - #define PRIV_STCRW 0x39 67 - #define PRIV_STCPS 0x3a 68 - #define PRIV_RCHP 0x3b 69 - #define PRIV_SCHM 0x3c 70 - #define PRIV_CHSC 0x5f 71 - #define PRIV_SIGA 0x74 72 - #define PRIV_XSCH 0x76 73 - #define PRIV_SQBS 0x8a 74 - #define PRIV_EQBS 0x9c 56 + #define PRIV_B2_SCLP_CALL 0x20 57 + #define PRIV_B2_CSCH 0x30 58 + #define PRIV_B2_HSCH 0x31 59 + #define PRIV_B2_MSCH 0x32 60 + #define PRIV_B2_SSCH 0x33 61 + #define PRIV_B2_STSCH 0x34 62 + #define PRIV_B2_TSCH 0x35 63 + #define PRIV_B2_TPI 0x36 64 + #define PRIV_B2_SAL 0x37 65 + #define PRIV_B2_RSCH 0x38 66 + #define PRIV_B2_STCRW 0x39 67 + #define PRIV_B2_STCPS 0x3a 68 + #define PRIV_B2_RCHP 0x3b 69 + #define PRIV_B2_SCHM 0x3c 70 + #define PRIV_B2_CHSC 0x5f 71 + #define PRIV_B2_SIGA 0x74 72 + #define PRIV_B2_XSCH 0x76 73 + 74 + #define PRIV_EB_SQBS 0x8a 75 + 76 + #define PRIV_B9_EQBS 0x9c 77 + 75 78 #define DIAG_IPL 0x308 76 79 #define DIAG_KVM_HYPERCALL 0x500 77 80 #define DIAG_KVM_BREAKPOINT 0x501 ··· 87 90 }; 88 91 89 92 static int cap_sync_regs; 93 + static int cap_async_pf; 90 94 91 95 static void *legacy_s390_alloc(size_t size); 92 96 93 97 int kvm_arch_init(KVMState *s) 94 98 { 95 99 cap_sync_regs = kvm_check_extension(s, KVM_CAP_SYNC_REGS); 100 + cap_async_pf = kvm_check_extension(s, KVM_CAP_ASYNC_PF); 96 101 if (!kvm_check_extension(s, KVM_CAP_S390_GMAP) 97 102 || !kvm_check_extension(s, KVM_CAP_S390_COW)) { 98 103 phys_mem_set_alloc(legacy_s390_alloc); ··· 178 183 return ret; 179 184 } 180 185 186 + if (cap_async_pf) { 187 + reg.id = KVM_REG_S390_PFTOKEN; 188 + reg.addr = (__u64)&(env->pfault_token); 189 + ret = kvm_vcpu_ioctl(cs, KVM_SET_ONE_REG, &reg); 190 + if (ret < 0) { 191 + return ret; 192 + } 193 + 194 + reg.id = KVM_REG_S390_PFCOMPARE; 195 + reg.addr = (__u64)&(env->pfault_compare); 196 + ret = kvm_vcpu_ioctl(cs, KVM_SET_ONE_REG, &reg); 197 + if (ret < 0) { 198 + return ret; 199 + } 200 + 201 + reg.id = KVM_REG_S390_PFSELECT; 202 + reg.addr = (__u64)&(env->pfault_select); 203 + ret = kvm_vcpu_ioctl(cs, KVM_SET_ONE_REG, &reg); 204 + if (ret < 0) { 205 + return ret; 206 + } 207 + } 208 + 181 209 if (cap_sync_regs && 182 210 cs->kvm_run->kvm_valid_regs & KVM_SYNC_ACRS && 183 211 cs->kvm_run->kvm_valid_regs & KVM_SYNC_CRS) { ··· 282 310 return r; 283 311 } 284 312 313 + if (cap_async_pf) { 314 + reg.id = KVM_REG_S390_PFTOKEN; 315 + reg.addr = (__u64)&(env->pfault_token); 316 + r = kvm_vcpu_ioctl(cs, KVM_GET_ONE_REG, &reg); 317 + if (r < 0) { 318 + return r; 319 + } 320 + 321 + reg.id = KVM_REG_S390_PFCOMPARE; 322 + reg.addr = (__u64)&(env->pfault_compare); 323 + r = kvm_vcpu_ioctl(cs, KVM_GET_ONE_REG, &reg); 324 + if (r < 0) { 325 + return r; 326 + } 327 + 328 + reg.id = KVM_REG_S390_PFSELECT; 329 + reg.addr = (__u64)&(env->pfault_select); 330 + r = kvm_vcpu_ioctl(cs, KVM_GET_ONE_REG, &reg); 331 + if (r < 0) { 332 + return r; 333 + } 334 + } 335 + 285 336 return 0; 286 337 } 287 338 ··· 392 443 uint16_t ipbh0) 393 444 { 394 445 CPUS390XState *env = &cpu->env; 395 - uint32_t sccb; 396 - uint64_t code; 446 + uint64_t sccb; 447 + uint32_t code; 397 448 int r = 0; 398 449 399 450 cpu_synchronize_state(CPU(cpu)); 400 - if (env->psw.mask & PSW_MASK_PSTATE) { 401 - enter_pgmcheck(cpu, PGM_PRIVILEGED); 402 - return 0; 403 - } 404 451 sccb = env->regs[ipbh0 & 0xf]; 405 452 code = env->regs[(ipbh0 & 0xf0) >> 4]; 406 453 407 - r = sclp_service_call(sccb, code); 454 + r = sclp_service_call(env, sccb, code); 408 455 if (r < 0) { 409 456 enter_pgmcheck(cpu, -r); 457 + } else { 458 + setcc(cpu, r); 410 459 } 411 - setcc(cpu, r); 412 460 413 461 return 0; 414 462 } 415 463 416 - static int kvm_handle_css_inst(S390CPU *cpu, struct kvm_run *run, 417 - uint8_t ipa0, uint8_t ipa1, uint8_t ipb) 464 + static int handle_b2(S390CPU *cpu, struct kvm_run *run, uint8_t ipa1) 418 465 { 419 466 CPUS390XState *env = &cpu->env; 420 - 421 - if (ipa0 != 0xb2) { 422 - /* Not handled for now. */ 423 - return -1; 424 - } 467 + int rc = 0; 468 + uint16_t ipbh0 = (run->s390_sieic.ipb & 0xffff0000) >> 16; 425 469 426 470 cpu_synchronize_state(CPU(cpu)); 427 471 428 472 switch (ipa1) { 429 - case PRIV_XSCH: 473 + case PRIV_B2_XSCH: 430 474 ioinst_handle_xsch(cpu, env->regs[1]); 431 475 break; 432 - case PRIV_CSCH: 476 + case PRIV_B2_CSCH: 433 477 ioinst_handle_csch(cpu, env->regs[1]); 434 478 break; 435 - case PRIV_HSCH: 479 + case PRIV_B2_HSCH: 436 480 ioinst_handle_hsch(cpu, env->regs[1]); 437 481 break; 438 - case PRIV_MSCH: 482 + case PRIV_B2_MSCH: 439 483 ioinst_handle_msch(cpu, env->regs[1], run->s390_sieic.ipb); 440 484 break; 441 - case PRIV_SSCH: 485 + case PRIV_B2_SSCH: 442 486 ioinst_handle_ssch(cpu, env->regs[1], run->s390_sieic.ipb); 443 487 break; 444 - case PRIV_STCRW: 488 + case PRIV_B2_STCRW: 445 489 ioinst_handle_stcrw(cpu, run->s390_sieic.ipb); 446 490 break; 447 - case PRIV_STSCH: 491 + case PRIV_B2_STSCH: 448 492 ioinst_handle_stsch(cpu, env->regs[1], run->s390_sieic.ipb); 449 493 break; 450 - case PRIV_TSCH: 494 + case PRIV_B2_TSCH: 451 495 /* We should only get tsch via KVM_EXIT_S390_TSCH. */ 452 496 fprintf(stderr, "Spurious tsch intercept\n"); 453 497 break; 454 - case PRIV_CHSC: 498 + case PRIV_B2_CHSC: 455 499 ioinst_handle_chsc(cpu, run->s390_sieic.ipb); 456 500 break; 457 - case PRIV_TPI: 501 + case PRIV_B2_TPI: 458 502 /* This should have been handled by kvm already. */ 459 503 fprintf(stderr, "Spurious tpi intercept\n"); 460 504 break; 461 - case PRIV_SCHM: 505 + case PRIV_B2_SCHM: 462 506 ioinst_handle_schm(cpu, env->regs[1], env->regs[2], 463 507 run->s390_sieic.ipb); 464 508 break; 465 - case PRIV_RSCH: 509 + case PRIV_B2_RSCH: 466 510 ioinst_handle_rsch(cpu, env->regs[1]); 467 511 break; 468 - case PRIV_RCHP: 512 + case PRIV_B2_RCHP: 469 513 ioinst_handle_rchp(cpu, env->regs[1]); 470 514 break; 471 - case PRIV_STCPS: 515 + case PRIV_B2_STCPS: 472 516 /* We do not provide this instruction, it is suppressed. */ 473 517 break; 474 - case PRIV_SAL: 518 + case PRIV_B2_SAL: 475 519 ioinst_handle_sal(cpu, env->regs[1]); 476 520 break; 477 - case PRIV_SIGA: 521 + case PRIV_B2_SIGA: 478 522 /* Not provided, set CC = 3 for subchannel not operational */ 479 523 setcc(cpu, 3); 480 524 break; 525 + case PRIV_B2_SCLP_CALL: 526 + rc = kvm_sclp_service_call(cpu, run, ipbh0); 527 + break; 481 528 default: 482 - return -1; 529 + rc = -1; 530 + DPRINTF("KVM: unhandled PRIV: 0xb2%x\n", ipa1); 531 + break; 483 532 } 484 533 485 - return 0; 534 + return rc; 486 535 } 487 536 488 - static int handle_priv(S390CPU *cpu, struct kvm_run *run, 489 - uint8_t ipa0, uint8_t ipa1) 537 + static int handle_b9(S390CPU *cpu, struct kvm_run *run, uint8_t ipa1) 490 538 { 491 539 int r = 0; 492 - uint16_t ipbh0 = (run->s390_sieic.ipb & 0xffff0000) >> 16; 493 - uint8_t ipb = run->s390_sieic.ipb & 0xff; 494 540 495 - DPRINTF("KVM: PRIV: %d\n", ipa1); 496 541 switch (ipa1) { 497 - case PRIV_SCLP_CALL: 498 - r = kvm_sclp_service_call(cpu, run, ipbh0); 499 - break; 500 - default: 501 - r = kvm_handle_css_inst(cpu, run, ipa0, ipa1, ipb); 502 - if (r == -1) { 503 - DPRINTF("KVM: unhandled PRIV: 0x%x\n", ipa1); 504 - } 505 - break; 542 + case PRIV_B9_EQBS: 543 + /* just inject exception */ 544 + r = -1; 545 + break; 546 + default: 547 + r = -1; 548 + DPRINTF("KVM: unhandled PRIV: 0xb9%x\n", ipa1); 549 + break; 550 + } 551 + 552 + return r; 553 + } 554 + 555 + static int handle_eb(S390CPU *cpu, struct kvm_run *run, uint8_t ipa1) 556 + { 557 + int r = 0; 558 + 559 + switch (ipa1) { 560 + case PRIV_EB_SQBS: 561 + /* just inject exception */ 562 + r = -1; 563 + break; 564 + default: 565 + r = -1; 566 + DPRINTF("KVM: unhandled PRIV: 0xeb%x\n", ipa1); 567 + break; 506 568 } 507 569 508 570 return r; ··· 511 573 static int handle_hypercall(S390CPU *cpu, struct kvm_run *run) 512 574 { 513 575 CPUS390XState *env = &cpu->env; 576 + int ret; 514 577 515 578 cpu_synchronize_state(CPU(cpu)); 516 - env->regs[2] = s390_virtio_hypercall(env); 579 + ret = s390_virtio_hypercall(env); 580 + if (ret == -EINVAL) { 581 + enter_pgmcheck(cpu, PGM_SPECIFICATION); 582 + return 0; 583 + } 517 584 518 - return 0; 585 + return ret; 519 586 } 520 587 521 588 static void kvm_handle_diag_308(S390CPU *cpu, struct kvm_run *run) ··· 576 643 return 0; 577 644 } 578 645 579 - static int s390_cpu_initial_reset(S390CPU *cpu) 646 + static void sigp_initial_cpu_reset(void *arg) 580 647 { 581 - CPUState *cs = CPU(cpu); 582 - CPUS390XState *env = &cpu->env; 583 - int i; 648 + CPUState *cpu = arg; 649 + S390CPUClass *scc = S390_CPU_GET_CLASS(cpu); 584 650 585 - s390_del_running_cpu(cpu); 586 - if (kvm_vcpu_ioctl(cs, KVM_S390_INITIAL_RESET, NULL) < 0) { 587 - perror("cannot init reset vcpu"); 588 - } 651 + cpu_synchronize_state(cpu); 652 + scc->initial_cpu_reset(cpu); 653 + } 589 654 590 - /* Manually zero out all registers */ 591 - cpu_synchronize_state(cs); 592 - for (i = 0; i < 16; i++) { 593 - env->regs[i] = 0; 594 - } 655 + static void sigp_cpu_reset(void *arg) 656 + { 657 + CPUState *cpu = arg; 658 + S390CPUClass *scc = S390_CPU_GET_CLASS(cpu); 595 659 596 - DPRINTF("DONE: SIGP initial reset: %p\n", env); 597 - return 0; 660 + cpu_synchronize_state(cpu); 661 + scc->cpu_reset(cpu); 598 662 } 599 663 600 664 #define SIGP_ORDER_MASK 0x000000ff ··· 628 692 cc = kvm_s390_cpu_restart(target_cpu); 629 693 break; 630 694 case SIGP_SET_ARCH: 631 - /* make the caller panic */ 632 - return -1; 695 + *statusreg &= 0xffffffff00000000UL; 696 + *statusreg |= SIGP_STAT_INVALID_PARAMETER; 697 + cc = 1; /* status stored */ 698 + break; 633 699 case SIGP_INITIAL_CPU_RESET: 634 - cc = s390_cpu_initial_reset(target_cpu); 700 + run_on_cpu(CPU(target_cpu), sigp_initial_cpu_reset, CPU(target_cpu)); 701 + cc = 0; 702 + break; 703 + case SIGP_CPU_RESET: 704 + run_on_cpu(CPU(target_cpu), sigp_cpu_reset, CPU(target_cpu)); 705 + cc = 0; 635 706 break; 636 707 default: 637 708 DPRINTF("KVM: unknown SIGP: 0x%x\n", order_code); ··· 656 727 run->s390_sieic.ipa, run->s390_sieic.ipb); 657 728 switch (ipa0) { 658 729 case IPA0_B2: 730 + r = handle_b2(cpu, run, ipa1); 731 + break; 659 732 case IPA0_B9: 733 + r = handle_b9(cpu, run, ipa1); 734 + break; 660 735 case IPA0_EB: 661 - r = handle_priv(cpu, run, ipa0 >> 8, ipa1); 736 + r = handle_eb(cpu, run, ipa1); 662 737 break; 663 738 case IPA0_DIAG: 664 739 r = handle_diag(cpu, run, run->s390_sieic.ipb);
+1 -1
target-s390x/misc_helper.c
··· 93 93 /* SCLP service call */ 94 94 uint32_t HELPER(servc)(CPUS390XState *env, uint64_t r1, uint64_t r2) 95 95 { 96 - int r = sclp_service_call(r1, r2); 96 + int r = sclp_service_call(env, r1, r2); 97 97 if (r < 0) { 98 98 program_interrupt(env, -r, 4); 99 99 return 0;
+5
trace-events
··· 1162 1162 virtio_ccw_interpret_ccw(int cssid, int ssid, int schid, int cmd_code) "VIRTIO-CCW: %x.%x.%04x: interpret command %x" 1163 1163 virtio_ccw_new_device(int cssid, int ssid, int schid, int devno, const char *devno_mode) "VIRTIO-CCW: add subchannel %x.%x.%04x, devno %04x (%s)" 1164 1164 1165 + # hw/intc/s390_flic.c 1166 + flic_create_device(int err) "flic: create device failed %d" 1167 + flic_no_device_api(int err) "flic: no Device Contral API support %d" 1168 + flic_reset_failed(int err) "flic: reset failed %d" 1169 + 1165 1170 # migration.c 1166 1171 migrate_set_state(int new_state) "new state %d" 1167 1172