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