1 /*
2 * virtio ccw machine
3 *
4 * Copyright 2012, 2020 IBM Corp.
5 * Copyright (c) 2009 Alexander Graf <agraf@suse.de>
6 * Author(s): Cornelia Huck <cornelia.huck@de.ibm.com>
7 * Janosch Frank <frankja@linux.ibm.com>
8 *
9 * This work is licensed under the terms of the GNU GPL, version 2 or (at
10 * your option) any later version. See the COPYING file in the top-level
11 * directory.
12 */
13
14 #include "qemu/osdep.h"
15 #include "qapi/error.h"
16 #include "exec/ram_addr.h"
17 #include "exec/confidential-guest-support.h"
18 #include "hw/boards.h"
19 #include "hw/s390x/s390-virtio-hcall.h"
20 #include "hw/s390x/sclp.h"
21 #include "hw/s390x/s390_flic.h"
22 #include "hw/s390x/ioinst.h"
23 #include "hw/s390x/css.h"
24 #include "virtio-ccw.h"
25 #include "qemu/config-file.h"
26 #include "qemu/ctype.h"
27 #include "qemu/error-report.h"
28 #include "qemu/option.h"
29 #include "qemu/qemu-print.h"
30 #include "qemu/units.h"
31 #include "hw/s390x/s390-pci-bus.h"
32 #include "sysemu/reset.h"
33 #include "hw/s390x/storage-keys.h"
34 #include "hw/s390x/storage-attributes.h"
35 #include "hw/s390x/event-facility.h"
36 #include "ipl.h"
37 #include "hw/s390x/s390-virtio-ccw.h"
38 #include "hw/s390x/css-bridge.h"
39 #include "hw/s390x/ap-bridge.h"
40 #include "migration/register.h"
41 #include "cpu_models.h"
42 #include "hw/nmi.h"
43 #include "hw/qdev-properties.h"
44 #include "hw/s390x/tod.h"
45 #include "sysemu/sysemu.h"
46 #include "sysemu/cpus.h"
47 #include "target/s390x/kvm/pv.h"
48 #include "migration/blocker.h"
49 #include "qapi/visitor.h"
50 #include "hw/s390x/cpu-topology.h"
51 #include CONFIG_DEVICES
52
53 static Error *pv_mig_blocker;
54
s390x_new_cpu(const char * typename,uint32_t core_id,Error ** errp)55 static S390CPU *s390x_new_cpu(const char *typename, uint32_t core_id,
56 Error **errp)
57 {
58 S390CPU *cpu = S390_CPU(object_new(typename));
59 S390CPU *ret = NULL;
60
61 if (!object_property_set_int(OBJECT(cpu), "core-id", core_id, errp)) {
62 goto out;
63 }
64 if (!qdev_realize(DEVICE(cpu), NULL, errp)) {
65 goto out;
66 }
67 ret = cpu;
68
69 out:
70 object_unref(OBJECT(cpu));
71 return ret;
72 }
73
s390_init_cpus(MachineState * machine)74 static void s390_init_cpus(MachineState *machine)
75 {
76 MachineClass *mc = MACHINE_GET_CLASS(machine);
77 S390CcwMachineClass *s390mc = S390_CCW_MACHINE_CLASS(mc);
78 int i;
79
80 if (machine->smp.threads > s390mc->max_threads) {
81 error_report("S390 does not support more than %d threads.",
82 s390mc->max_threads);
83 exit(1);
84 }
85
86 /* initialize possible_cpus */
87 mc->possible_cpu_arch_ids(machine);
88
89 for (i = 0; i < machine->smp.cpus; i++) {
90 s390x_new_cpu(machine->cpu_type, i, &error_fatal);
91 }
92 }
93
94 static const char *const reset_dev_types[] = {
95 TYPE_VIRTUAL_CSS_BRIDGE,
96 "s390-sclp-event-facility",
97 "s390-flic",
98 "diag288",
99 TYPE_S390_PCI_HOST_BRIDGE,
100 TYPE_AP_BRIDGE,
101 };
102
subsystem_reset(void)103 static void subsystem_reset(void)
104 {
105 DeviceState *dev;
106 int i;
107
108 /*
109 * ISM firmware is sensitive to unexpected changes to the IOMMU, which can
110 * occur during reset of the vfio-pci device (unmap of entire aperture).
111 * Ensure any passthrough ISM devices are reset now, while CPUs are paused
112 * but before vfio-pci cleanup occurs.
113 */
114 s390_pci_ism_reset();
115
116 for (i = 0; i < ARRAY_SIZE(reset_dev_types); i++) {
117 dev = DEVICE(object_resolve_path_type("", reset_dev_types[i], NULL));
118 if (dev) {
119 device_cold_reset(dev);
120 }
121 }
122 if (s390_has_topology()) {
123 s390_topology_reset();
124 }
125 }
126
virtio_ccw_hcall_notify(const uint64_t * args)127 static int virtio_ccw_hcall_notify(const uint64_t *args)
128 {
129 uint64_t subch_id = args[0];
130 uint64_t data = args[1];
131 SubchDev *sch;
132 VirtIODevice *vdev;
133 int cssid, ssid, schid, m;
134 uint16_t vq_idx = data;
135
136 if (ioinst_disassemble_sch_ident(subch_id, &m, &cssid, &ssid, &schid)) {
137 return -EINVAL;
138 }
139 sch = css_find_subch(m, cssid, ssid, schid);
140 if (!sch || !css_subch_visible(sch)) {
141 return -EINVAL;
142 }
143
144 vdev = virtio_ccw_get_vdev(sch);
145 if (vq_idx >= VIRTIO_QUEUE_MAX || !virtio_queue_get_num(vdev, vq_idx)) {
146 return -EINVAL;
147 }
148
149 if (virtio_vdev_has_feature(vdev, VIRTIO_F_NOTIFICATION_DATA)) {
150 virtio_queue_set_shadow_avail_idx(virtio_get_queue(vdev, vq_idx),
151 (data >> 16) & 0xFFFF);
152 }
153
154 virtio_queue_notify(vdev, vq_idx);
155 return 0;
156 }
157
virtio_ccw_hcall_early_printk(const uint64_t * args)158 static int virtio_ccw_hcall_early_printk(const uint64_t *args)
159 {
160 uint64_t mem = args[0];
161 MachineState *ms = MACHINE(qdev_get_machine());
162
163 if (mem < ms->ram_size) {
164 /* Early printk */
165 return 0;
166 }
167 return -EINVAL;
168 }
169
virtio_ccw_register_hcalls(void)170 static void virtio_ccw_register_hcalls(void)
171 {
172 s390_register_virtio_hypercall(KVM_S390_VIRTIO_CCW_NOTIFY,
173 virtio_ccw_hcall_notify);
174 /* Tolerate early printk. */
175 s390_register_virtio_hypercall(KVM_S390_VIRTIO_NOTIFY,
176 virtio_ccw_hcall_early_printk);
177 }
178
s390_memory_init(MemoryRegion * ram)179 static void s390_memory_init(MemoryRegion *ram)
180 {
181 MemoryRegion *sysmem = get_system_memory();
182
183 if (!QEMU_IS_ALIGNED(memory_region_size(ram), 1 * MiB)) {
184 /*
185 * SCLP cannot possibly expose smaller granularity right now and KVM
186 * cannot handle smaller granularity. As we don't support NUMA, the
187 * region size directly corresponds to machine->ram_size, and the region
188 * is a single RAM memory region.
189 */
190 error_report("ram size must be multiples of 1 MiB");
191 exit(EXIT_FAILURE);
192 }
193
194 /* allocate RAM for core */
195 memory_region_add_subregion(sysmem, 0, ram);
196
197 /*
198 * Configure the maximum page size. As no memory devices were created
199 * yet, this is the page size of initial memory only.
200 */
201 s390_set_max_pagesize(qemu_maxrampagesize(), &error_fatal);
202 /* Initialize storage key device */
203 s390_skeys_init();
204 /* Initialize storage attributes device */
205 s390_stattrib_init();
206 }
207
s390_init_ipl_dev(const char * kernel_filename,const char * kernel_cmdline,const char * initrd_filename,const char * firmware,bool enforce_bios)208 static void s390_init_ipl_dev(const char *kernel_filename,
209 const char *kernel_cmdline,
210 const char *initrd_filename, const char *firmware,
211 bool enforce_bios)
212 {
213 Object *new = object_new(TYPE_S390_IPL);
214 DeviceState *dev = DEVICE(new);
215
216 if (kernel_filename) {
217 qdev_prop_set_string(dev, "kernel", kernel_filename);
218 }
219 if (initrd_filename) {
220 qdev_prop_set_string(dev, "initrd", initrd_filename);
221 }
222 qdev_prop_set_string(dev, "cmdline", kernel_cmdline);
223 qdev_prop_set_string(dev, "firmware", firmware);
224 qdev_prop_set_bit(dev, "enforce_bios", enforce_bios);
225 object_property_add_child(qdev_get_machine(), TYPE_S390_IPL,
226 new);
227 object_unref(new);
228 qdev_realize(dev, NULL, &error_fatal);
229 }
230
s390_create_virtio_net(BusState * bus,const char * name)231 static void s390_create_virtio_net(BusState *bus, const char *name)
232 {
233 DeviceState *dev;
234 int cnt = 0;
235
236 while ((dev = qemu_create_nic_device(name, true, "virtio"))) {
237 g_autofree char *childname = g_strdup_printf("%s[%d]", name, cnt++);
238 object_property_add_child(OBJECT(bus), childname, OBJECT(dev));
239 qdev_realize_and_unref(dev, bus, &error_fatal);
240 }
241 }
242
s390_create_sclpconsole(SCLPDevice * sclp,const char * type,Chardev * chardev)243 static void s390_create_sclpconsole(SCLPDevice *sclp,
244 const char *type, Chardev *chardev)
245 {
246 SCLPEventFacility *ef = sclp->event_facility;
247 BusState *ev_fac_bus = sclp_get_event_facility_bus(ef);
248 DeviceState *dev;
249
250 dev = qdev_new(type);
251 object_property_add_child(OBJECT(ef), type, OBJECT(dev));
252 qdev_prop_set_chr(dev, "chardev", chardev);
253 qdev_realize_and_unref(dev, ev_fac_bus, &error_fatal);
254 }
255
ccw_init(MachineState * machine)256 static void ccw_init(MachineState *machine)
257 {
258 MachineClass *mc = MACHINE_GET_CLASS(machine);
259 S390CcwMachineState *ms = S390_CCW_MACHINE(machine);
260 int ret;
261 VirtualCssBus *css_bus;
262 DeviceState *dev;
263
264 ms->sclp = SCLP(object_new(TYPE_SCLP));
265 object_property_add_child(OBJECT(machine), TYPE_SCLP, OBJECT(ms->sclp));
266 qdev_realize_and_unref(DEVICE(ms->sclp), NULL, &error_fatal);
267
268 /* init memory + setup max page size. Required for the CPU model */
269 s390_memory_init(machine->ram);
270
271 /* init CPUs (incl. CPU model) early so s390_has_feature() works */
272 s390_init_cpus(machine);
273
274 /* Need CPU model to be determined before we can set up PV */
275 if (machine->cgs) {
276 confidential_guest_kvm_init(machine->cgs, &error_fatal);
277 }
278
279 s390_flic_init();
280
281 /* init the SIGP facility */
282 s390_init_sigp();
283
284 /* create AP bridge and bus(es) */
285 s390_init_ap();
286
287 /* get a BUS */
288 css_bus = virtual_css_bus_init();
289 s390_init_ipl_dev(machine->kernel_filename, machine->kernel_cmdline,
290 machine->initrd_filename,
291 machine->firmware ?: "s390-ccw.img",
292 true);
293
294 dev = qdev_new(TYPE_S390_PCI_HOST_BRIDGE);
295 object_property_add_child(qdev_get_machine(), TYPE_S390_PCI_HOST_BRIDGE,
296 OBJECT(dev));
297 sysbus_realize_and_unref(SYS_BUS_DEVICE(dev), &error_fatal);
298
299 /* register hypercalls */
300 virtio_ccw_register_hcalls();
301
302 s390_enable_css_support(s390_cpu_addr2state(0));
303
304 ret = css_create_css_image(VIRTUAL_CSSID, true);
305 assert(ret == 0);
306
307 css_register_vmstate();
308
309 /* Create VirtIO network adapters */
310 s390_create_virtio_net(BUS(css_bus), mc->default_nic);
311
312 /* init consoles */
313 if (serial_hd(0)) {
314 s390_create_sclpconsole(ms->sclp, "sclpconsole", serial_hd(0));
315 }
316 if (serial_hd(1)) {
317 s390_create_sclpconsole(ms->sclp, "sclplmconsole", serial_hd(1));
318 }
319
320 /* init the TOD clock */
321 s390_init_tod();
322 }
323
s390_cpu_plug(HotplugHandler * hotplug_dev,DeviceState * dev,Error ** errp)324 static void s390_cpu_plug(HotplugHandler *hotplug_dev,
325 DeviceState *dev, Error **errp)
326 {
327 ERRP_GUARD();
328 MachineState *ms = MACHINE(hotplug_dev);
329 S390CPU *cpu = S390_CPU(dev);
330
331 g_assert(!ms->possible_cpus->cpus[cpu->env.core_id].cpu);
332 ms->possible_cpus->cpus[cpu->env.core_id].cpu = CPU(dev);
333
334 if (s390_has_topology()) {
335 s390_topology_setup_cpu(ms, cpu, errp);
336 if (*errp) {
337 return;
338 }
339 }
340
341 if (dev->hotplugged) {
342 raise_irq_cpu_hotplug();
343 }
344 }
345
s390_do_cpu_ipl(CPUState * cs,run_on_cpu_data arg)346 static inline void s390_do_cpu_ipl(CPUState *cs, run_on_cpu_data arg)
347 {
348 S390CPU *cpu = S390_CPU(cs);
349
350 s390_ipl_prepare_cpu(cpu);
351 s390_cpu_set_state(S390_CPU_STATE_OPERATING, cpu);
352 }
353
s390_machine_unprotect(S390CcwMachineState * ms)354 static void s390_machine_unprotect(S390CcwMachineState *ms)
355 {
356 if (!s390_pv_vm_try_disable_async(ms)) {
357 s390_pv_vm_disable();
358 }
359 ms->pv = false;
360 migrate_del_blocker(&pv_mig_blocker);
361 ram_block_discard_disable(false);
362 }
363
s390_machine_protect(S390CcwMachineState * ms)364 static int s390_machine_protect(S390CcwMachineState *ms)
365 {
366 Error *local_err = NULL;
367 int rc;
368
369 /*
370 * Discarding of memory in RAM blocks does not work as expected with
371 * protected VMs. Sharing and unsharing pages would be required. Disable
372 * it for now, until until we have a solution to make at least Linux
373 * guests either support it (e.g., virtio-balloon) or fail gracefully.
374 */
375 rc = ram_block_discard_disable(true);
376 if (rc) {
377 error_report("protected VMs: cannot disable RAM discard");
378 return rc;
379 }
380
381 error_setg(&pv_mig_blocker,
382 "protected VMs are currently not migratable.");
383 rc = migrate_add_blocker(&pv_mig_blocker, &local_err);
384 if (rc) {
385 ram_block_discard_disable(false);
386 error_report_err(local_err);
387 return rc;
388 }
389
390 /* Create SE VM */
391 rc = s390_pv_vm_enable();
392 if (rc) {
393 ram_block_discard_disable(false);
394 migrate_del_blocker(&pv_mig_blocker);
395 return rc;
396 }
397
398 ms->pv = true;
399
400 /* Will return 0 if API is not available since it's not vital */
401 rc = s390_pv_query_info();
402 if (rc) {
403 goto out_err;
404 }
405
406 /* Set SE header and unpack */
407 rc = s390_ipl_prepare_pv_header(&local_err);
408 if (rc) {
409 goto out_err;
410 }
411
412 /* Decrypt image */
413 rc = s390_ipl_pv_unpack();
414 if (rc) {
415 goto out_err;
416 }
417
418 /* Verify integrity */
419 rc = s390_pv_verify();
420 if (rc) {
421 goto out_err;
422 }
423 return rc;
424
425 out_err:
426 if (local_err) {
427 error_report_err(local_err);
428 }
429 s390_machine_unprotect(ms);
430 return rc;
431 }
432
s390_pv_prepare_reset(S390CcwMachineState * ms)433 static void s390_pv_prepare_reset(S390CcwMachineState *ms)
434 {
435 CPUState *cs;
436
437 if (!s390_is_pv()) {
438 return;
439 }
440 /* Unsharing requires all cpus to be stopped */
441 CPU_FOREACH(cs) {
442 s390_cpu_set_state(S390_CPU_STATE_STOPPED, S390_CPU(cs));
443 }
444 s390_pv_unshare();
445 s390_pv_prep_reset();
446 }
447
s390_machine_reset(MachineState * machine,ResetType type)448 static void s390_machine_reset(MachineState *machine, ResetType type)
449 {
450 S390CcwMachineState *ms = S390_CCW_MACHINE(machine);
451 enum s390_reset reset_type;
452 CPUState *cs, *t;
453 S390CPU *cpu;
454
455 /* get the reset parameters, reset them once done */
456 s390_ipl_get_reset_request(&cs, &reset_type);
457
458 /* all CPUs are paused and synchronized at this point */
459 s390_cmma_reset();
460
461 cpu = S390_CPU(cs);
462
463 switch (reset_type) {
464 case S390_RESET_EXTERNAL:
465 case S390_RESET_REIPL:
466 /*
467 * Reset the subsystem which includes a AP reset. If a PV
468 * guest had APQNs attached the AP reset is a prerequisite to
469 * unprotecting since the UV checks if all APQNs are reset.
470 */
471 subsystem_reset();
472 if (s390_is_pv()) {
473 s390_machine_unprotect(ms);
474 }
475
476 /*
477 * Device reset includes CPU clear resets so this has to be
478 * done AFTER the unprotect call above.
479 */
480 qemu_devices_reset(type);
481 s390_crypto_reset();
482
483 /* configure and start the ipl CPU only */
484 run_on_cpu(cs, s390_do_cpu_ipl, RUN_ON_CPU_NULL);
485 break;
486 case S390_RESET_MODIFIED_CLEAR:
487 /*
488 * Subsystem reset needs to be done before we unshare memory
489 * and lose access to VIRTIO structures in guest memory.
490 */
491 subsystem_reset();
492 s390_crypto_reset();
493 s390_pv_prepare_reset(ms);
494 CPU_FOREACH(t) {
495 run_on_cpu(t, s390_do_cpu_full_reset, RUN_ON_CPU_NULL);
496 }
497 run_on_cpu(cs, s390_do_cpu_load_normal, RUN_ON_CPU_NULL);
498 break;
499 case S390_RESET_LOAD_NORMAL:
500 /*
501 * Subsystem reset needs to be done before we unshare memory
502 * and lose access to VIRTIO structures in guest memory.
503 */
504 subsystem_reset();
505 s390_pv_prepare_reset(ms);
506 CPU_FOREACH(t) {
507 if (t == cs) {
508 continue;
509 }
510 run_on_cpu(t, s390_do_cpu_reset, RUN_ON_CPU_NULL);
511 }
512 run_on_cpu(cs, s390_do_cpu_initial_reset, RUN_ON_CPU_NULL);
513 run_on_cpu(cs, s390_do_cpu_load_normal, RUN_ON_CPU_NULL);
514 break;
515 case S390_RESET_PV: /* Subcode 10 */
516 subsystem_reset();
517 s390_crypto_reset();
518
519 CPU_FOREACH(t) {
520 if (t == cs) {
521 continue;
522 }
523 run_on_cpu(t, s390_do_cpu_full_reset, RUN_ON_CPU_NULL);
524 }
525 run_on_cpu(cs, s390_do_cpu_reset, RUN_ON_CPU_NULL);
526
527 if (s390_machine_protect(ms)) {
528 s390_pv_inject_reset_error(cs);
529 /*
530 * Continue after the diag308 so the guest knows something
531 * went wrong.
532 */
533 s390_cpu_set_state(S390_CPU_STATE_OPERATING, cpu);
534 return;
535 }
536
537 run_on_cpu(cs, s390_do_cpu_load_normal, RUN_ON_CPU_NULL);
538 break;
539 default:
540 g_assert_not_reached();
541 }
542
543 CPU_FOREACH(t) {
544 run_on_cpu(t, s390_do_cpu_set_diag318, RUN_ON_CPU_HOST_ULONG(0));
545 }
546 s390_ipl_clear_reset_request();
547 }
548
s390_machine_device_plug(HotplugHandler * hotplug_dev,DeviceState * dev,Error ** errp)549 static void s390_machine_device_plug(HotplugHandler *hotplug_dev,
550 DeviceState *dev, Error **errp)
551 {
552 if (object_dynamic_cast(OBJECT(dev), TYPE_CPU)) {
553 s390_cpu_plug(hotplug_dev, dev, errp);
554 }
555 }
556
s390_machine_device_unplug_request(HotplugHandler * hotplug_dev,DeviceState * dev,Error ** errp)557 static void s390_machine_device_unplug_request(HotplugHandler *hotplug_dev,
558 DeviceState *dev, Error **errp)
559 {
560 if (object_dynamic_cast(OBJECT(dev), TYPE_CPU)) {
561 error_setg(errp, "CPU hot unplug not supported on this machine");
562 return;
563 }
564 }
565
s390_cpu_index_to_props(MachineState * ms,unsigned cpu_index)566 static CpuInstanceProperties s390_cpu_index_to_props(MachineState *ms,
567 unsigned cpu_index)
568 {
569 MachineClass *mc = MACHINE_GET_CLASS(ms);
570 const CPUArchIdList *possible_cpus = mc->possible_cpu_arch_ids(ms);
571
572 assert(cpu_index < possible_cpus->len);
573 return possible_cpus->cpus[cpu_index].props;
574 }
575
s390_possible_cpu_arch_ids(MachineState * ms)576 static const CPUArchIdList *s390_possible_cpu_arch_ids(MachineState *ms)
577 {
578 int i;
579 unsigned int max_cpus = ms->smp.max_cpus;
580
581 if (ms->possible_cpus) {
582 g_assert(ms->possible_cpus && ms->possible_cpus->len == max_cpus);
583 return ms->possible_cpus;
584 }
585
586 ms->possible_cpus = g_malloc0(sizeof(CPUArchIdList) +
587 sizeof(CPUArchId) * max_cpus);
588 ms->possible_cpus->len = max_cpus;
589 for (i = 0; i < ms->possible_cpus->len; i++) {
590 CpuInstanceProperties *props = &ms->possible_cpus->cpus[i].props;
591
592 ms->possible_cpus->cpus[i].type = ms->cpu_type;
593 ms->possible_cpus->cpus[i].vcpus_count = 1;
594 ms->possible_cpus->cpus[i].arch_id = i;
595
596 props->has_core_id = true;
597 props->core_id = i;
598 props->has_socket_id = true;
599 props->socket_id = s390_std_socket(i, &ms->smp);
600 props->has_book_id = true;
601 props->book_id = s390_std_book(i, &ms->smp);
602 props->has_drawer_id = true;
603 props->drawer_id = s390_std_drawer(i, &ms->smp);
604 }
605
606 return ms->possible_cpus;
607 }
608
s390_get_hotplug_handler(MachineState * machine,DeviceState * dev)609 static HotplugHandler *s390_get_hotplug_handler(MachineState *machine,
610 DeviceState *dev)
611 {
612 if (object_dynamic_cast(OBJECT(dev), TYPE_CPU)) {
613 return HOTPLUG_HANDLER(machine);
614 }
615 return NULL;
616 }
617
s390_nmi(NMIState * n,int cpu_index,Error ** errp)618 static void s390_nmi(NMIState *n, int cpu_index, Error **errp)
619 {
620 CPUState *cs = qemu_get_cpu(cpu_index);
621
622 s390_cpu_restart(S390_CPU(cs));
623 }
624
s390_fixup_ram_size(ram_addr_t sz)625 static ram_addr_t s390_fixup_ram_size(ram_addr_t sz)
626 {
627 /* same logic as in sclp.c */
628 int increment_size = 20;
629 ram_addr_t newsz;
630
631 while ((sz >> increment_size) > MAX_STORAGE_INCREMENTS) {
632 increment_size++;
633 }
634 newsz = sz >> increment_size << increment_size;
635
636 if (sz != newsz) {
637 qemu_printf("Ram size %" PRIu64 "MB was fixed up to %" PRIu64
638 "MB to match machine restrictions. Consider updating "
639 "the guest definition.\n", (uint64_t) (sz / MiB),
640 (uint64_t) (newsz / MiB));
641 }
642 return newsz;
643 }
644
machine_get_aes_key_wrap(Object * obj,Error ** errp)645 static inline bool machine_get_aes_key_wrap(Object *obj, Error **errp)
646 {
647 S390CcwMachineState *ms = S390_CCW_MACHINE(obj);
648
649 return ms->aes_key_wrap;
650 }
651
machine_set_aes_key_wrap(Object * obj,bool value,Error ** errp)652 static inline void machine_set_aes_key_wrap(Object *obj, bool value,
653 Error **errp)
654 {
655 S390CcwMachineState *ms = S390_CCW_MACHINE(obj);
656
657 ms->aes_key_wrap = value;
658 }
659
machine_get_dea_key_wrap(Object * obj,Error ** errp)660 static inline bool machine_get_dea_key_wrap(Object *obj, Error **errp)
661 {
662 S390CcwMachineState *ms = S390_CCW_MACHINE(obj);
663
664 return ms->dea_key_wrap;
665 }
666
machine_set_dea_key_wrap(Object * obj,bool value,Error ** errp)667 static inline void machine_set_dea_key_wrap(Object *obj, bool value,
668 Error **errp)
669 {
670 S390CcwMachineState *ms = S390_CCW_MACHINE(obj);
671
672 ms->dea_key_wrap = value;
673 }
674
675 static S390CcwMachineClass *current_mc;
676
677 /*
678 * Get the class of the s390-ccw-virtio machine that is currently in use.
679 * Note: libvirt is using the "none" machine to probe for the features of the
680 * host CPU, so in case this is called with the "none" machine, the function
681 * returns the TYPE_S390_CCW_MACHINE base class. In this base class, all the
682 * various "*_allowed" variables are enabled, so that the *_allowed() wrappers
683 * below return the correct default value for the "none" machine.
684 *
685 * Attention! Do *not* add additional new wrappers for CPU features (e.g. like
686 * the ri_allowed() wrapper) via this mechanism anymore. CPU features should
687 * be handled via the CPU models, i.e. checking with cpu_model_allowed() during
688 * CPU initialization and s390_has_feat() later should be sufficient.
689 */
get_machine_class(void)690 static S390CcwMachineClass *get_machine_class(void)
691 {
692 if (unlikely(!current_mc)) {
693 /*
694 * No s390 ccw machine was instantiated, we are likely to
695 * be called for the 'none' machine. The properties will
696 * have their after-initialization values.
697 */
698 current_mc = S390_CCW_MACHINE_CLASS(
699 object_class_by_name(TYPE_S390_CCW_MACHINE));
700 }
701 return current_mc;
702 }
703
ri_allowed(void)704 bool ri_allowed(void)
705 {
706 return get_machine_class()->ri_allowed;
707 }
708
cpu_model_allowed(void)709 bool cpu_model_allowed(void)
710 {
711 return get_machine_class()->cpu_model_allowed;
712 }
713
hpage_1m_allowed(void)714 bool hpage_1m_allowed(void)
715 {
716 return get_machine_class()->hpage_1m_allowed;
717 }
718
machine_get_loadparm(Object * obj,Visitor * v,const char * name,void * opaque,Error ** errp)719 static void machine_get_loadparm(Object *obj, Visitor *v,
720 const char *name, void *opaque,
721 Error **errp)
722 {
723 S390CcwMachineState *ms = S390_CCW_MACHINE(obj);
724 char *str = g_strndup((char *) ms->loadparm, sizeof(ms->loadparm));
725
726 visit_type_str(v, name, &str, errp);
727 g_free(str);
728 }
729
machine_set_loadparm(Object * obj,Visitor * v,const char * name,void * opaque,Error ** errp)730 static void machine_set_loadparm(Object *obj, Visitor *v,
731 const char *name, void *opaque,
732 Error **errp)
733 {
734 S390CcwMachineState *ms = S390_CCW_MACHINE(obj);
735 char *val;
736
737 if (!visit_type_str(v, name, &val, errp)) {
738 return;
739 }
740
741 s390_ipl_fmt_loadparm(ms->loadparm, val, errp);
742 }
743
ccw_machine_class_init(ObjectClass * oc,void * data)744 static void ccw_machine_class_init(ObjectClass *oc, void *data)
745 {
746 MachineClass *mc = MACHINE_CLASS(oc);
747 NMIClass *nc = NMI_CLASS(oc);
748 HotplugHandlerClass *hc = HOTPLUG_HANDLER_CLASS(oc);
749 S390CcwMachineClass *s390mc = S390_CCW_MACHINE_CLASS(mc);
750
751 s390mc->ri_allowed = true;
752 s390mc->cpu_model_allowed = true;
753 s390mc->hpage_1m_allowed = true;
754 s390mc->max_threads = 1;
755 mc->init = ccw_init;
756 mc->reset = s390_machine_reset;
757 mc->block_default_type = IF_VIRTIO;
758 mc->no_cdrom = 1;
759 mc->no_floppy = 1;
760 mc->no_parallel = 1;
761 mc->no_sdcard = 1;
762 mc->max_cpus = S390_MAX_CPUS;
763 mc->has_hotpluggable_cpus = true;
764 mc->smp_props.books_supported = true;
765 mc->smp_props.drawers_supported = true;
766 assert(!mc->get_hotplug_handler);
767 mc->get_hotplug_handler = s390_get_hotplug_handler;
768 mc->cpu_index_to_instance_props = s390_cpu_index_to_props;
769 mc->possible_cpu_arch_ids = s390_possible_cpu_arch_ids;
770 /* it is overridden with 'host' cpu *in kvm_arch_init* */
771 mc->default_cpu_type = S390_CPU_TYPE_NAME("qemu");
772 hc->plug = s390_machine_device_plug;
773 hc->unplug_request = s390_machine_device_unplug_request;
774 nc->nmi_monitor_handler = s390_nmi;
775 mc->default_ram_id = "s390.ram";
776 mc->default_nic = "virtio-net-ccw";
777
778 object_class_property_add_bool(oc, "aes-key-wrap",
779 machine_get_aes_key_wrap,
780 machine_set_aes_key_wrap);
781 object_class_property_set_description(oc, "aes-key-wrap",
782 "enable/disable AES key wrapping using the CPACF wrapping key");
783
784 object_class_property_add_bool(oc, "dea-key-wrap",
785 machine_get_dea_key_wrap,
786 machine_set_dea_key_wrap);
787 object_class_property_set_description(oc, "dea-key-wrap",
788 "enable/disable DEA key wrapping using the CPACF wrapping key");
789
790 object_class_property_add(oc, "loadparm", "loadparm",
791 machine_get_loadparm, machine_set_loadparm,
792 NULL, NULL);
793 object_class_property_set_description(oc, "loadparm",
794 "Up to 8 chars in set of [A-Za-z0-9. ] (lower case chars converted"
795 " to upper case) to pass to machine loader, boot manager,"
796 " and guest kernel");
797 }
798
s390_machine_initfn(Object * obj)799 static inline void s390_machine_initfn(Object *obj)
800 {
801 S390CcwMachineState *ms = S390_CCW_MACHINE(obj);
802
803 ms->aes_key_wrap = true;
804 ms->dea_key_wrap = true;
805 }
806
807 static const TypeInfo ccw_machine_info = {
808 .name = TYPE_S390_CCW_MACHINE,
809 .parent = TYPE_MACHINE,
810 .abstract = true,
811 .instance_size = sizeof(S390CcwMachineState),
812 .instance_init = s390_machine_initfn,
813 .class_size = sizeof(S390CcwMachineClass),
814 .class_init = ccw_machine_class_init,
815 .interfaces = (InterfaceInfo[]) {
816 { TYPE_NMI },
817 { TYPE_HOTPLUG_HANDLER},
818 { }
819 },
820 };
821
822 #define DEFINE_CCW_MACHINE_IMPL(latest, ...) \
823 static void MACHINE_VER_SYM(class_init, ccw, __VA_ARGS__)( \
824 ObjectClass *oc, \
825 void *data) \
826 { \
827 MachineClass *mc = MACHINE_CLASS(oc); \
828 MACHINE_VER_SYM(class_options, ccw, __VA_ARGS__)(mc); \
829 mc->desc = "Virtual s390x machine (version " MACHINE_VER_STR(__VA_ARGS__) ")"; \
830 MACHINE_VER_DEPRECATION(__VA_ARGS__); \
831 if (latest) { \
832 mc->alias = "s390-ccw-virtio"; \
833 mc->is_default = true; \
834 } \
835 } \
836 static void MACHINE_VER_SYM(instance_init, ccw, __VA_ARGS__)(Object *obj) \
837 { \
838 MachineState *machine = MACHINE(obj); \
839 current_mc = S390_CCW_MACHINE_CLASS(MACHINE_GET_CLASS(machine)); \
840 MACHINE_VER_SYM(instance_options, ccw, __VA_ARGS__)(machine); \
841 } \
842 static const TypeInfo MACHINE_VER_SYM(info, ccw, __VA_ARGS__) = \
843 { \
844 .name = MACHINE_VER_TYPE_NAME("s390-ccw-virtio", __VA_ARGS__), \
845 .parent = TYPE_S390_CCW_MACHINE, \
846 .class_init = MACHINE_VER_SYM(class_init, ccw, __VA_ARGS__), \
847 .instance_init = MACHINE_VER_SYM(instance_init, ccw, __VA_ARGS__), \
848 }; \
849 static void MACHINE_VER_SYM(register, ccw, __VA_ARGS__)(void) \
850 { \
851 MACHINE_VER_DELETION(__VA_ARGS__); \
852 type_register_static(&MACHINE_VER_SYM(info, ccw, __VA_ARGS__)); \
853 } \
854 type_init(MACHINE_VER_SYM(register, ccw, __VA_ARGS__))
855
856 #define DEFINE_CCW_MACHINE_AS_LATEST(major, minor) \
857 DEFINE_CCW_MACHINE_IMPL(true, major, minor)
858
859 #define DEFINE_CCW_MACHINE(major, minor) \
860 DEFINE_CCW_MACHINE_IMPL(false, major, minor)
861
862
ccw_machine_9_2_instance_options(MachineState * machine)863 static void ccw_machine_9_2_instance_options(MachineState *machine)
864 {
865 }
866
ccw_machine_9_2_class_options(MachineClass * mc)867 static void ccw_machine_9_2_class_options(MachineClass *mc)
868 {
869 }
870 DEFINE_CCW_MACHINE_AS_LATEST(9, 2);
871
ccw_machine_9_1_instance_options(MachineState * machine)872 static void ccw_machine_9_1_instance_options(MachineState *machine)
873 {
874 ccw_machine_9_2_instance_options(machine);
875 }
876
ccw_machine_9_1_class_options(MachineClass * mc)877 static void ccw_machine_9_1_class_options(MachineClass *mc)
878 {
879 ccw_machine_9_2_class_options(mc);
880 compat_props_add(mc->compat_props, hw_compat_9_1, hw_compat_9_1_len);
881 }
882 DEFINE_CCW_MACHINE(9, 1);
883
ccw_machine_9_0_instance_options(MachineState * machine)884 static void ccw_machine_9_0_instance_options(MachineState *machine)
885 {
886 ccw_machine_9_1_instance_options(machine);
887 }
888
ccw_machine_9_0_class_options(MachineClass * mc)889 static void ccw_machine_9_0_class_options(MachineClass *mc)
890 {
891 static GlobalProperty compat[] = {
892 { TYPE_QEMU_S390_FLIC, "migrate-all-state", "off", },
893 };
894
895 ccw_machine_9_1_class_options(mc);
896 compat_props_add(mc->compat_props, hw_compat_9_0, hw_compat_9_0_len);
897 compat_props_add(mc->compat_props, compat, G_N_ELEMENTS(compat));
898 }
899 DEFINE_CCW_MACHINE(9, 0);
900
ccw_machine_8_2_instance_options(MachineState * machine)901 static void ccw_machine_8_2_instance_options(MachineState *machine)
902 {
903 ccw_machine_9_0_instance_options(machine);
904 }
905
ccw_machine_8_2_class_options(MachineClass * mc)906 static void ccw_machine_8_2_class_options(MachineClass *mc)
907 {
908 ccw_machine_9_0_class_options(mc);
909 compat_props_add(mc->compat_props, hw_compat_8_2, hw_compat_8_2_len);
910 }
911 DEFINE_CCW_MACHINE(8, 2);
912
ccw_machine_8_1_instance_options(MachineState * machine)913 static void ccw_machine_8_1_instance_options(MachineState *machine)
914 {
915 ccw_machine_8_2_instance_options(machine);
916 }
917
ccw_machine_8_1_class_options(MachineClass * mc)918 static void ccw_machine_8_1_class_options(MachineClass *mc)
919 {
920 ccw_machine_8_2_class_options(mc);
921 compat_props_add(mc->compat_props, hw_compat_8_1, hw_compat_8_1_len);
922 mc->smp_props.drawers_supported = false;
923 mc->smp_props.books_supported = false;
924 }
925 DEFINE_CCW_MACHINE(8, 1);
926
ccw_machine_8_0_instance_options(MachineState * machine)927 static void ccw_machine_8_0_instance_options(MachineState *machine)
928 {
929 ccw_machine_8_1_instance_options(machine);
930 }
931
ccw_machine_8_0_class_options(MachineClass * mc)932 static void ccw_machine_8_0_class_options(MachineClass *mc)
933 {
934 ccw_machine_8_1_class_options(mc);
935 compat_props_add(mc->compat_props, hw_compat_8_0, hw_compat_8_0_len);
936 }
937 DEFINE_CCW_MACHINE(8, 0);
938
ccw_machine_7_2_instance_options(MachineState * machine)939 static void ccw_machine_7_2_instance_options(MachineState *machine)
940 {
941 ccw_machine_8_0_instance_options(machine);
942 }
943
ccw_machine_7_2_class_options(MachineClass * mc)944 static void ccw_machine_7_2_class_options(MachineClass *mc)
945 {
946 ccw_machine_8_0_class_options(mc);
947 compat_props_add(mc->compat_props, hw_compat_7_2, hw_compat_7_2_len);
948 }
949 DEFINE_CCW_MACHINE(7, 2);
950
ccw_machine_7_1_instance_options(MachineState * machine)951 static void ccw_machine_7_1_instance_options(MachineState *machine)
952 {
953 static const S390FeatInit qemu_cpu_feat = { S390_FEAT_LIST_QEMU_V7_1 };
954
955 ccw_machine_7_2_instance_options(machine);
956 s390_cpudef_featoff_greater(16, 1, S390_FEAT_PAIE);
957 s390_set_qemu_cpu_model(0x8561, 15, 1, qemu_cpu_feat);
958 }
959
ccw_machine_7_1_class_options(MachineClass * mc)960 static void ccw_machine_7_1_class_options(MachineClass *mc)
961 {
962 S390CcwMachineClass *s390mc = S390_CCW_MACHINE_CLASS(mc);
963 static GlobalProperty compat[] = {
964 { TYPE_S390_PCI_DEVICE, "interpret", "off", },
965 { TYPE_S390_PCI_DEVICE, "forwarding-assist", "off", },
966 };
967
968 ccw_machine_7_2_class_options(mc);
969 compat_props_add(mc->compat_props, hw_compat_7_1, hw_compat_7_1_len);
970 compat_props_add(mc->compat_props, compat, G_N_ELEMENTS(compat));
971 s390mc->max_threads = S390_MAX_CPUS;
972 }
973 DEFINE_CCW_MACHINE(7, 1);
974
ccw_machine_7_0_instance_options(MachineState * machine)975 static void ccw_machine_7_0_instance_options(MachineState *machine)
976 {
977 static const S390FeatInit qemu_cpu_feat = { S390_FEAT_LIST_QEMU_V7_0 };
978
979 ccw_machine_7_1_instance_options(machine);
980 s390_set_qemu_cpu_model(0x8561, 15, 1, qemu_cpu_feat);
981 }
982
ccw_machine_7_0_class_options(MachineClass * mc)983 static void ccw_machine_7_0_class_options(MachineClass *mc)
984 {
985 ccw_machine_7_1_class_options(mc);
986 compat_props_add(mc->compat_props, hw_compat_7_0, hw_compat_7_0_len);
987 }
988 DEFINE_CCW_MACHINE(7, 0);
989
ccw_machine_6_2_instance_options(MachineState * machine)990 static void ccw_machine_6_2_instance_options(MachineState *machine)
991 {
992 static const S390FeatInit qemu_cpu_feat = { S390_FEAT_LIST_QEMU_V6_2 };
993
994 ccw_machine_7_0_instance_options(machine);
995 s390_set_qemu_cpu_model(0x3906, 14, 2, qemu_cpu_feat);
996 }
997
ccw_machine_6_2_class_options(MachineClass * mc)998 static void ccw_machine_6_2_class_options(MachineClass *mc)
999 {
1000 ccw_machine_7_0_class_options(mc);
1001 compat_props_add(mc->compat_props, hw_compat_6_2, hw_compat_6_2_len);
1002 }
1003 DEFINE_CCW_MACHINE(6, 2);
1004
ccw_machine_6_1_instance_options(MachineState * machine)1005 static void ccw_machine_6_1_instance_options(MachineState *machine)
1006 {
1007 ccw_machine_6_2_instance_options(machine);
1008 s390_cpudef_featoff_greater(16, 1, S390_FEAT_NNPA);
1009 s390_cpudef_featoff_greater(16, 1, S390_FEAT_VECTOR_PACKED_DECIMAL_ENH2);
1010 s390_cpudef_featoff_greater(16, 1, S390_FEAT_BEAR_ENH);
1011 s390_cpudef_featoff_greater(16, 1, S390_FEAT_RDP);
1012 s390_cpudef_featoff_greater(16, 1, S390_FEAT_PAI);
1013 }
1014
ccw_machine_6_1_class_options(MachineClass * mc)1015 static void ccw_machine_6_1_class_options(MachineClass *mc)
1016 {
1017 ccw_machine_6_2_class_options(mc);
1018 compat_props_add(mc->compat_props, hw_compat_6_1, hw_compat_6_1_len);
1019 mc->smp_props.prefer_sockets = true;
1020 }
1021 DEFINE_CCW_MACHINE(6, 1);
1022
ccw_machine_6_0_instance_options(MachineState * machine)1023 static void ccw_machine_6_0_instance_options(MachineState *machine)
1024 {
1025 static const S390FeatInit qemu_cpu_feat = { S390_FEAT_LIST_QEMU_V6_0 };
1026
1027 ccw_machine_6_1_instance_options(machine);
1028 s390_set_qemu_cpu_model(0x2964, 13, 2, qemu_cpu_feat);
1029 }
1030
ccw_machine_6_0_class_options(MachineClass * mc)1031 static void ccw_machine_6_0_class_options(MachineClass *mc)
1032 {
1033 ccw_machine_6_1_class_options(mc);
1034 compat_props_add(mc->compat_props, hw_compat_6_0, hw_compat_6_0_len);
1035 }
1036 DEFINE_CCW_MACHINE(6, 0);
1037
ccw_machine_5_2_instance_options(MachineState * machine)1038 static void ccw_machine_5_2_instance_options(MachineState *machine)
1039 {
1040 ccw_machine_6_0_instance_options(machine);
1041 }
1042
ccw_machine_5_2_class_options(MachineClass * mc)1043 static void ccw_machine_5_2_class_options(MachineClass *mc)
1044 {
1045 ccw_machine_6_0_class_options(mc);
1046 compat_props_add(mc->compat_props, hw_compat_5_2, hw_compat_5_2_len);
1047 }
1048 DEFINE_CCW_MACHINE(5, 2);
1049
ccw_machine_5_1_instance_options(MachineState * machine)1050 static void ccw_machine_5_1_instance_options(MachineState *machine)
1051 {
1052 ccw_machine_5_2_instance_options(machine);
1053 }
1054
ccw_machine_5_1_class_options(MachineClass * mc)1055 static void ccw_machine_5_1_class_options(MachineClass *mc)
1056 {
1057 ccw_machine_5_2_class_options(mc);
1058 compat_props_add(mc->compat_props, hw_compat_5_1, hw_compat_5_1_len);
1059 }
1060 DEFINE_CCW_MACHINE(5, 1);
1061
ccw_machine_5_0_instance_options(MachineState * machine)1062 static void ccw_machine_5_0_instance_options(MachineState *machine)
1063 {
1064 ccw_machine_5_1_instance_options(machine);
1065 }
1066
ccw_machine_5_0_class_options(MachineClass * mc)1067 static void ccw_machine_5_0_class_options(MachineClass *mc)
1068 {
1069 ccw_machine_5_1_class_options(mc);
1070 compat_props_add(mc->compat_props, hw_compat_5_0, hw_compat_5_0_len);
1071 }
1072 DEFINE_CCW_MACHINE(5, 0);
1073
ccw_machine_4_2_instance_options(MachineState * machine)1074 static void ccw_machine_4_2_instance_options(MachineState *machine)
1075 {
1076 ccw_machine_5_0_instance_options(machine);
1077 }
1078
ccw_machine_4_2_class_options(MachineClass * mc)1079 static void ccw_machine_4_2_class_options(MachineClass *mc)
1080 {
1081 ccw_machine_5_0_class_options(mc);
1082 mc->fixup_ram_size = s390_fixup_ram_size;
1083 compat_props_add(mc->compat_props, hw_compat_4_2, hw_compat_4_2_len);
1084 }
1085 DEFINE_CCW_MACHINE(4, 2);
1086
ccw_machine_4_1_instance_options(MachineState * machine)1087 static void ccw_machine_4_1_instance_options(MachineState *machine)
1088 {
1089 static const S390FeatInit qemu_cpu_feat = { S390_FEAT_LIST_QEMU_V4_1 };
1090 ccw_machine_4_2_instance_options(machine);
1091 s390_set_qemu_cpu_model(0x2964, 13, 2, qemu_cpu_feat);
1092 }
1093
ccw_machine_4_1_class_options(MachineClass * mc)1094 static void ccw_machine_4_1_class_options(MachineClass *mc)
1095 {
1096 ccw_machine_4_2_class_options(mc);
1097 compat_props_add(mc->compat_props, hw_compat_4_1, hw_compat_4_1_len);
1098 }
1099 DEFINE_CCW_MACHINE(4, 1);
1100
ccw_machine_4_0_instance_options(MachineState * machine)1101 static void ccw_machine_4_0_instance_options(MachineState *machine)
1102 {
1103 static const S390FeatInit qemu_cpu_feat = { S390_FEAT_LIST_QEMU_V4_0 };
1104 ccw_machine_4_1_instance_options(machine);
1105 s390_set_qemu_cpu_model(0x2827, 12, 2, qemu_cpu_feat);
1106 }
1107
ccw_machine_4_0_class_options(MachineClass * mc)1108 static void ccw_machine_4_0_class_options(MachineClass *mc)
1109 {
1110 ccw_machine_4_1_class_options(mc);
1111 compat_props_add(mc->compat_props, hw_compat_4_0, hw_compat_4_0_len);
1112 }
1113 DEFINE_CCW_MACHINE(4, 0);
1114
ccw_machine_3_1_instance_options(MachineState * machine)1115 static void ccw_machine_3_1_instance_options(MachineState *machine)
1116 {
1117 static const S390FeatInit qemu_cpu_feat = { S390_FEAT_LIST_QEMU_V3_1 };
1118 ccw_machine_4_0_instance_options(machine);
1119 s390_cpudef_featoff_greater(14, 1, S390_FEAT_MULTIPLE_EPOCH);
1120 s390_cpudef_group_featoff_greater(14, 1, S390_FEAT_GROUP_MULTIPLE_EPOCH_PTFF);
1121 s390_set_qemu_cpu_model(0x2827, 12, 2, qemu_cpu_feat);
1122 }
1123
ccw_machine_3_1_class_options(MachineClass * mc)1124 static void ccw_machine_3_1_class_options(MachineClass *mc)
1125 {
1126 ccw_machine_4_0_class_options(mc);
1127 compat_props_add(mc->compat_props, hw_compat_3_1, hw_compat_3_1_len);
1128 }
1129 DEFINE_CCW_MACHINE(3, 1);
1130
ccw_machine_3_0_instance_options(MachineState * machine)1131 static void ccw_machine_3_0_instance_options(MachineState *machine)
1132 {
1133 ccw_machine_3_1_instance_options(machine);
1134 }
1135
ccw_machine_3_0_class_options(MachineClass * mc)1136 static void ccw_machine_3_0_class_options(MachineClass *mc)
1137 {
1138 S390CcwMachineClass *s390mc = S390_CCW_MACHINE_CLASS(mc);
1139
1140 s390mc->hpage_1m_allowed = false;
1141 ccw_machine_3_1_class_options(mc);
1142 compat_props_add(mc->compat_props, hw_compat_3_0, hw_compat_3_0_len);
1143 }
1144 DEFINE_CCW_MACHINE(3, 0);
1145
ccw_machine_2_12_instance_options(MachineState * machine)1146 static void ccw_machine_2_12_instance_options(MachineState *machine)
1147 {
1148 ccw_machine_3_0_instance_options(machine);
1149 s390_cpudef_featoff_greater(11, 1, S390_FEAT_PPA15);
1150 s390_cpudef_featoff_greater(11, 1, S390_FEAT_BPB);
1151 }
1152
ccw_machine_2_12_class_options(MachineClass * mc)1153 static void ccw_machine_2_12_class_options(MachineClass *mc)
1154 {
1155 ccw_machine_3_0_class_options(mc);
1156 compat_props_add(mc->compat_props, hw_compat_2_12, hw_compat_2_12_len);
1157 }
1158 DEFINE_CCW_MACHINE(2, 12);
1159
1160 #ifdef CONFIG_S390X_LEGACY_CPUS
1161
ccw_machine_2_11_instance_options(MachineState * machine)1162 static void ccw_machine_2_11_instance_options(MachineState *machine)
1163 {
1164 static const S390FeatInit qemu_cpu_feat = { S390_FEAT_LIST_QEMU_V2_11 };
1165 ccw_machine_2_12_instance_options(machine);
1166
1167 /* before 2.12 we emulated the very first z900 */
1168 s390_set_qemu_cpu_model(0x2064, 7, 1, qemu_cpu_feat);
1169 }
1170
ccw_machine_2_11_class_options(MachineClass * mc)1171 static void ccw_machine_2_11_class_options(MachineClass *mc)
1172 {
1173 static GlobalProperty compat[] = {
1174 { TYPE_SCLP_EVENT_FACILITY, "allow_all_mask_sizes", "off", },
1175 };
1176
1177 ccw_machine_2_12_class_options(mc);
1178 compat_props_add(mc->compat_props, hw_compat_2_11, hw_compat_2_11_len);
1179 compat_props_add(mc->compat_props, compat, G_N_ELEMENTS(compat));
1180 }
1181 DEFINE_CCW_MACHINE(2, 11);
1182
ccw_machine_2_10_instance_options(MachineState * machine)1183 static void ccw_machine_2_10_instance_options(MachineState *machine)
1184 {
1185 ccw_machine_2_11_instance_options(machine);
1186 }
1187
ccw_machine_2_10_class_options(MachineClass * mc)1188 static void ccw_machine_2_10_class_options(MachineClass *mc)
1189 {
1190 ccw_machine_2_11_class_options(mc);
1191 compat_props_add(mc->compat_props, hw_compat_2_10, hw_compat_2_10_len);
1192 }
1193 DEFINE_CCW_MACHINE(2, 10);
1194
ccw_machine_2_9_instance_options(MachineState * machine)1195 static void ccw_machine_2_9_instance_options(MachineState *machine)
1196 {
1197 ccw_machine_2_10_instance_options(machine);
1198 s390_cpudef_featoff_greater(12, 1, S390_FEAT_ESOP);
1199 s390_cpudef_featoff_greater(12, 1, S390_FEAT_SIDE_EFFECT_ACCESS_ESOP2);
1200 s390_cpudef_featoff_greater(12, 1, S390_FEAT_ZPCI);
1201 s390_cpudef_featoff_greater(12, 1, S390_FEAT_ADAPTER_INT_SUPPRESSION);
1202 s390_cpudef_featoff_greater(12, 1, S390_FEAT_ADAPTER_EVENT_NOTIFICATION);
1203 css_migration_enabled = false;
1204 }
1205
ccw_machine_2_9_class_options(MachineClass * mc)1206 static void ccw_machine_2_9_class_options(MachineClass *mc)
1207 {
1208 static GlobalProperty compat[] = {
1209 { TYPE_S390_STATTRIB, "migration-enabled", "off", },
1210 { TYPE_S390_FLIC_COMMON, "migration-enabled", "off", },
1211 };
1212
1213 ccw_machine_2_10_class_options(mc);
1214 compat_props_add(mc->compat_props, hw_compat_2_9, hw_compat_2_9_len);
1215 compat_props_add(mc->compat_props, compat, G_N_ELEMENTS(compat));
1216 }
1217 DEFINE_CCW_MACHINE(2, 9);
1218
ccw_machine_2_8_instance_options(MachineState * machine)1219 static void ccw_machine_2_8_instance_options(MachineState *machine)
1220 {
1221 ccw_machine_2_9_instance_options(machine);
1222 }
1223
ccw_machine_2_8_class_options(MachineClass * mc)1224 static void ccw_machine_2_8_class_options(MachineClass *mc)
1225 {
1226 static GlobalProperty compat[] = {
1227 { TYPE_S390_FLIC_COMMON, "adapter_routes_max_batch", "64", },
1228 };
1229
1230 ccw_machine_2_9_class_options(mc);
1231 compat_props_add(mc->compat_props, hw_compat_2_8, hw_compat_2_8_len);
1232 compat_props_add(mc->compat_props, compat, G_N_ELEMENTS(compat));
1233 }
1234 DEFINE_CCW_MACHINE(2, 8);
1235
ccw_machine_2_7_instance_options(MachineState * machine)1236 static void ccw_machine_2_7_instance_options(MachineState *machine)
1237 {
1238 ccw_machine_2_8_instance_options(machine);
1239 }
1240
ccw_machine_2_7_class_options(MachineClass * mc)1241 static void ccw_machine_2_7_class_options(MachineClass *mc)
1242 {
1243 S390CcwMachineClass *s390mc = S390_CCW_MACHINE_CLASS(mc);
1244
1245 s390mc->cpu_model_allowed = false;
1246 ccw_machine_2_8_class_options(mc);
1247 compat_props_add(mc->compat_props, hw_compat_2_7, hw_compat_2_7_len);
1248 }
1249 DEFINE_CCW_MACHINE(2, 7);
1250
ccw_machine_2_6_instance_options(MachineState * machine)1251 static void ccw_machine_2_6_instance_options(MachineState *machine)
1252 {
1253 ccw_machine_2_7_instance_options(machine);
1254 }
1255
ccw_machine_2_6_class_options(MachineClass * mc)1256 static void ccw_machine_2_6_class_options(MachineClass *mc)
1257 {
1258 S390CcwMachineClass *s390mc = S390_CCW_MACHINE_CLASS(mc);
1259 static GlobalProperty compat[] = {
1260 { TYPE_S390_IPL, "iplbext_migration", "off", },
1261 { TYPE_VIRTUAL_CSS_BRIDGE, "css_dev_path", "off", },
1262 };
1263
1264 s390mc->ri_allowed = false;
1265 ccw_machine_2_7_class_options(mc);
1266 compat_props_add(mc->compat_props, hw_compat_2_6, hw_compat_2_6_len);
1267 compat_props_add(mc->compat_props, compat, G_N_ELEMENTS(compat));
1268 }
1269 DEFINE_CCW_MACHINE(2, 6);
1270
ccw_machine_2_5_instance_options(MachineState * machine)1271 static void ccw_machine_2_5_instance_options(MachineState *machine)
1272 {
1273 ccw_machine_2_6_instance_options(machine);
1274 }
1275
ccw_machine_2_5_class_options(MachineClass * mc)1276 static void ccw_machine_2_5_class_options(MachineClass *mc)
1277 {
1278 ccw_machine_2_6_class_options(mc);
1279 compat_props_add(mc->compat_props, hw_compat_2_5, hw_compat_2_5_len);
1280 }
1281 DEFINE_CCW_MACHINE(2, 5);
1282
ccw_machine_2_4_instance_options(MachineState * machine)1283 static void ccw_machine_2_4_instance_options(MachineState *machine)
1284 {
1285 ccw_machine_2_5_instance_options(machine);
1286 }
1287
ccw_machine_2_4_class_options(MachineClass * mc)1288 static void ccw_machine_2_4_class_options(MachineClass *mc)
1289 {
1290 static GlobalProperty compat[] = {
1291 { TYPE_S390_SKEYS, "migration-enabled", "off", },
1292 { "virtio-blk-ccw", "max_revision", "0", },
1293 { "virtio-balloon-ccw", "max_revision", "0", },
1294 { "virtio-serial-ccw", "max_revision", "0", },
1295 { "virtio-9p-ccw", "max_revision", "0", },
1296 { "virtio-rng-ccw", "max_revision", "0", },
1297 { "virtio-net-ccw", "max_revision", "0", },
1298 { "virtio-scsi-ccw", "max_revision", "0", },
1299 { "vhost-scsi-ccw", "max_revision", "0", },
1300 };
1301
1302 ccw_machine_2_5_class_options(mc);
1303 compat_props_add(mc->compat_props, hw_compat_2_4, hw_compat_2_4_len);
1304 compat_props_add(mc->compat_props, compat, G_N_ELEMENTS(compat));
1305 }
1306 DEFINE_CCW_MACHINE(2, 4);
1307
1308 #endif
1309
ccw_machine_register_types(void)1310 static void ccw_machine_register_types(void)
1311 {
1312 type_register_static(&ccw_machine_info);
1313 }
1314
1315 type_init(ccw_machine_register_types)
1316