xref: /openbmc/qemu/hw/s390x/s390-virtio-ccw.c (revision 44b1ff31)
1 /*
2  * virtio ccw machine
3  *
4  * Copyright 2012 IBM Corp.
5  * Copyright (c) 2009 Alexander Graf <agraf@suse.de>
6  * Author(s): Cornelia Huck <cornelia.huck@de.ibm.com>
7  *
8  * This work is licensed under the terms of the GNU GPL, version 2 or (at
9  * your option) any later version. See the COPYING file in the top-level
10  * directory.
11  */
12 
13 #include "qemu/osdep.h"
14 #include "qapi/error.h"
15 #include "qemu-common.h"
16 #include "cpu.h"
17 #include "hw/boards.h"
18 #include "exec/address-spaces.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/error-report.h"
27 #include "s390-pci-bus.h"
28 #include "hw/s390x/storage-keys.h"
29 #include "hw/s390x/storage-attributes.h"
30 #include "hw/compat.h"
31 #include "ipl.h"
32 #include "hw/s390x/s390-virtio-ccw.h"
33 #include "hw/s390x/css-bridge.h"
34 #include "migration/register.h"
35 #include "cpu_models.h"
36 #include "qapi/qmp/qerror.h"
37 #include "hw/nmi.h"
38 
39 S390CPU *s390_cpu_addr2state(uint16_t cpu_addr)
40 {
41     static MachineState *ms;
42 
43     if (!ms) {
44         ms = MACHINE(qdev_get_machine());
45         g_assert(ms->possible_cpus);
46     }
47 
48     /* CPU address corresponds to the core_id and the index */
49     if (cpu_addr >= ms->possible_cpus->len) {
50         return NULL;
51     }
52     return S390_CPU(ms->possible_cpus->cpus[cpu_addr].cpu);
53 }
54 
55 static void s390_init_cpus(MachineState *machine)
56 {
57     MachineClass *mc = MACHINE_GET_CLASS(machine);
58     const char *typename;
59     gchar **model_pieces;
60     ObjectClass *oc;
61     CPUClass *cc;
62     int i;
63 
64     if (machine->cpu_model == NULL) {
65         machine->cpu_model = s390_default_cpu_model_name();
66     }
67     if (tcg_enabled() && max_cpus > 1) {
68         error_report("Number of SMP CPUs requested (%d) exceeds max CPUs "
69                      "supported by TCG (1) on s390x", max_cpus);
70         exit(1);
71     }
72 
73     /* initialize possible_cpus */
74     mc->possible_cpu_arch_ids(machine);
75 
76     model_pieces = g_strsplit(machine->cpu_model, ",", 2);
77     if (!model_pieces[0]) {
78         error_report("Invalid/empty CPU model name");
79         exit(1);
80     }
81 
82     oc = cpu_class_by_name(TYPE_S390_CPU, model_pieces[0]);
83     if (!oc) {
84         error_report("Unable to find CPU definition: %s", model_pieces[0]);
85         exit(1);
86     }
87     typename = object_class_get_name(oc);
88     cc = CPU_CLASS(oc);
89     /* after parsing, properties will be applied to all *typename* instances */
90     cc->parse_features(typename, model_pieces[1], &error_fatal);
91     g_strfreev(model_pieces);
92 
93     for (i = 0; i < smp_cpus; i++) {
94         s390x_new_cpu(typename, i, &error_fatal);
95     }
96 }
97 
98 static const char *const reset_dev_types[] = {
99     TYPE_VIRTUAL_CSS_BRIDGE,
100     "s390-sclp-event-facility",
101     "s390-flic",
102     "diag288",
103 };
104 
105 void subsystem_reset(void)
106 {
107     DeviceState *dev;
108     int i;
109 
110     for (i = 0; i < ARRAY_SIZE(reset_dev_types); i++) {
111         dev = DEVICE(object_resolve_path_type("", reset_dev_types[i], NULL));
112         if (dev) {
113             qdev_reset_all(dev);
114         }
115     }
116 }
117 
118 static int virtio_ccw_hcall_notify(const uint64_t *args)
119 {
120     uint64_t subch_id = args[0];
121     uint64_t queue = args[1];
122     SubchDev *sch;
123     int cssid, ssid, schid, m;
124 
125     if (ioinst_disassemble_sch_ident(subch_id, &m, &cssid, &ssid, &schid)) {
126         return -EINVAL;
127     }
128     sch = css_find_subch(m, cssid, ssid, schid);
129     if (!sch || !css_subch_visible(sch)) {
130         return -EINVAL;
131     }
132     if (queue >= VIRTIO_QUEUE_MAX) {
133         return -EINVAL;
134     }
135     virtio_queue_notify(virtio_ccw_get_vdev(sch), queue);
136     return 0;
137 
138 }
139 
140 static int virtio_ccw_hcall_early_printk(const uint64_t *args)
141 {
142     uint64_t mem = args[0];
143 
144     if (mem < ram_size) {
145         /* Early printk */
146         return 0;
147     }
148     return -EINVAL;
149 }
150 
151 static void virtio_ccw_register_hcalls(void)
152 {
153     s390_register_virtio_hypercall(KVM_S390_VIRTIO_CCW_NOTIFY,
154                                    virtio_ccw_hcall_notify);
155     /* Tolerate early printk. */
156     s390_register_virtio_hypercall(KVM_S390_VIRTIO_NOTIFY,
157                                    virtio_ccw_hcall_early_printk);
158 }
159 
160 static void s390_memory_init(ram_addr_t mem_size)
161 {
162     MemoryRegion *sysmem = get_system_memory();
163     MemoryRegion *ram = g_new(MemoryRegion, 1);
164 
165     /* allocate RAM for core */
166     memory_region_allocate_system_memory(ram, NULL, "s390.ram", mem_size);
167     memory_region_add_subregion(sysmem, 0, ram);
168 
169     /* Initialize storage key device */
170     s390_skeys_init();
171     /* Initialize storage attributes device */
172     s390_stattrib_init();
173 }
174 
175 #define S390_TOD_CLOCK_VALUE_MISSING    0x00
176 #define S390_TOD_CLOCK_VALUE_PRESENT    0x01
177 
178 static void gtod_save(QEMUFile *f, void *opaque)
179 {
180     uint64_t tod_low;
181     uint8_t tod_high;
182     int r;
183 
184     r = s390_get_clock(&tod_high, &tod_low);
185     if (r) {
186         warn_report("Unable to get guest clock for migration: %s",
187                     strerror(-r));
188         error_printf("Guest clock will not be migrated "
189                      "which could cause the guest to hang.");
190         qemu_put_byte(f, S390_TOD_CLOCK_VALUE_MISSING);
191         return;
192     }
193 
194     qemu_put_byte(f, S390_TOD_CLOCK_VALUE_PRESENT);
195     qemu_put_byte(f, tod_high);
196     qemu_put_be64(f, tod_low);
197 }
198 
199 static int gtod_load(QEMUFile *f, void *opaque, int version_id)
200 {
201     uint64_t tod_low;
202     uint8_t tod_high;
203     int r;
204 
205     if (qemu_get_byte(f) == S390_TOD_CLOCK_VALUE_MISSING) {
206         warn_report("Guest clock was not migrated. This could "
207                     "cause the guest to hang.");
208         return 0;
209     }
210 
211     tod_high = qemu_get_byte(f);
212     tod_low = qemu_get_be64(f);
213 
214     r = s390_set_clock(&tod_high, &tod_low);
215     if (r) {
216         warn_report("Unable to set guest clock for migration: %s",
217                     strerror(-r));
218         error_printf("Guest clock will not be restored "
219                      "which could cause the guest to hang.");
220     }
221 
222     return 0;
223 }
224 
225 static SaveVMHandlers savevm_gtod = {
226     .save_state = gtod_save,
227     .load_state = gtod_load,
228 };
229 
230 static void s390_init_ipl_dev(const char *kernel_filename,
231                               const char *kernel_cmdline,
232                               const char *initrd_filename, const char *firmware,
233                               const char *netboot_fw, bool enforce_bios)
234 {
235     Object *new = object_new(TYPE_S390_IPL);
236     DeviceState *dev = DEVICE(new);
237 
238     if (kernel_filename) {
239         qdev_prop_set_string(dev, "kernel", kernel_filename);
240     }
241     if (initrd_filename) {
242         qdev_prop_set_string(dev, "initrd", initrd_filename);
243     }
244     qdev_prop_set_string(dev, "cmdline", kernel_cmdline);
245     qdev_prop_set_string(dev, "firmware", firmware);
246     qdev_prop_set_string(dev, "netboot_fw", netboot_fw);
247     qdev_prop_set_bit(dev, "enforce_bios", enforce_bios);
248     object_property_add_child(qdev_get_machine(), TYPE_S390_IPL,
249                               new, NULL);
250     object_unref(new);
251     qdev_init_nofail(dev);
252 }
253 
254 static void s390_create_virtio_net(BusState *bus, const char *name)
255 {
256     int i;
257 
258     for (i = 0; i < nb_nics; i++) {
259         NICInfo *nd = &nd_table[i];
260         DeviceState *dev;
261 
262         if (!nd->model) {
263             nd->model = g_strdup("virtio");
264         }
265 
266         qemu_check_nic_model(nd, "virtio");
267 
268         dev = qdev_create(bus, name);
269         qdev_set_nic_properties(dev, nd);
270         qdev_init_nofail(dev);
271     }
272 }
273 
274 static void ccw_init(MachineState *machine)
275 {
276     int ret;
277     VirtualCssBus *css_bus;
278 
279     s390_sclp_init();
280     s390_memory_init(machine->ram_size);
281 
282     /* init CPUs (incl. CPU model) early so s390_has_feature() works */
283     s390_init_cpus(machine);
284 
285     s390_flic_init();
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, "s390-ccw.img",
291                       "s390-netboot.img", true);
292 
293     if (s390_has_feat(S390_FEAT_ZPCI)) {
294         DeviceState *dev = qdev_create(NULL, TYPE_S390_PCI_HOST_BRIDGE);
295         object_property_add_child(qdev_get_machine(),
296                                   TYPE_S390_PCI_HOST_BRIDGE,
297                                   OBJECT(dev), NULL);
298         qdev_init_nofail(dev);
299     }
300 
301     /* register hypercalls */
302     virtio_ccw_register_hcalls();
303 
304     s390_enable_css_support(s390_cpu_addr2state(0));
305     /*
306      * Non mcss-e enabled guests only see the devices from the default
307      * css, which is determined by the value of the squash_mcss property.
308      * Note: we must not squash non virtual devices to css 0xFE.
309      */
310     if (css_bus->squash_mcss) {
311         ret = css_create_css_image(0, true);
312     } else {
313         ret = css_create_css_image(VIRTUAL_CSSID, true);
314     }
315     assert(ret == 0);
316 
317     /* Create VirtIO network adapters */
318     s390_create_virtio_net(BUS(css_bus), "virtio-net-ccw");
319 
320     /* Register savevm handler for guest TOD clock */
321     register_savevm_live(NULL, "todclock", 0, 1, &savevm_gtod, NULL);
322 }
323 
324 static void s390_cpu_plug(HotplugHandler *hotplug_dev,
325                         DeviceState *dev, Error **errp)
326 {
327     MachineState *ms = MACHINE(hotplug_dev);
328     S390CPU *cpu = S390_CPU(dev);
329 
330     g_assert(!ms->possible_cpus->cpus[cpu->env.core_id].cpu);
331     ms->possible_cpus->cpus[cpu->env.core_id].cpu = OBJECT(dev);
332 }
333 
334 static void s390_machine_reset(void)
335 {
336     S390CPU *ipl_cpu = S390_CPU(qemu_get_cpu(0));
337 
338     s390_cmma_reset();
339     qemu_devices_reset();
340     s390_crypto_reset();
341 
342     /* all cpus are stopped - configure and start the ipl cpu only */
343     s390_ipl_prepare_cpu(ipl_cpu);
344     s390_cpu_set_state(CPU_STATE_OPERATING, ipl_cpu);
345 }
346 
347 static void s390_machine_device_plug(HotplugHandler *hotplug_dev,
348                                      DeviceState *dev, Error **errp)
349 {
350     if (object_dynamic_cast(OBJECT(dev), TYPE_CPU)) {
351         s390_cpu_plug(hotplug_dev, dev, errp);
352     }
353 }
354 
355 static void s390_machine_device_unplug_request(HotplugHandler *hotplug_dev,
356                                                DeviceState *dev, Error **errp)
357 {
358     if (object_dynamic_cast(OBJECT(dev), TYPE_CPU)) {
359         error_setg(errp, "CPU hot unplug not supported on this machine");
360         return;
361     }
362 }
363 
364 static CpuInstanceProperties s390_cpu_index_to_props(MachineState *machine,
365                                                      unsigned cpu_index)
366 {
367     g_assert(machine->possible_cpus && cpu_index < machine->possible_cpus->len);
368 
369     return machine->possible_cpus->cpus[cpu_index].props;
370 }
371 
372 static const CPUArchIdList *s390_possible_cpu_arch_ids(MachineState *ms)
373 {
374     int i;
375 
376     if (ms->possible_cpus) {
377         g_assert(ms->possible_cpus && ms->possible_cpus->len == max_cpus);
378         return ms->possible_cpus;
379     }
380 
381     ms->possible_cpus = g_malloc0(sizeof(CPUArchIdList) +
382                                   sizeof(CPUArchId) * max_cpus);
383     ms->possible_cpus->len = max_cpus;
384     for (i = 0; i < ms->possible_cpus->len; i++) {
385         ms->possible_cpus->cpus[i].vcpus_count = 1;
386         ms->possible_cpus->cpus[i].arch_id = i;
387         ms->possible_cpus->cpus[i].props.has_core_id = true;
388         ms->possible_cpus->cpus[i].props.core_id = i;
389     }
390 
391     return ms->possible_cpus;
392 }
393 
394 static HotplugHandler *s390_get_hotplug_handler(MachineState *machine,
395                                                 DeviceState *dev)
396 {
397     if (object_dynamic_cast(OBJECT(dev), TYPE_CPU)) {
398         return HOTPLUG_HANDLER(machine);
399     }
400     return NULL;
401 }
402 
403 static void s390_hot_add_cpu(const int64_t id, Error **errp)
404 {
405     MachineState *machine = MACHINE(qdev_get_machine());
406     ObjectClass *oc;
407 
408     g_assert(machine->possible_cpus->cpus[0].cpu);
409     oc = OBJECT_CLASS(CPU_GET_CLASS(machine->possible_cpus->cpus[0].cpu));
410 
411     s390x_new_cpu(object_class_get_name(oc), id, errp);
412 }
413 
414 static void s390_nmi(NMIState *n, int cpu_index, Error **errp)
415 {
416     CPUState *cs = qemu_get_cpu(cpu_index);
417 
418     if (s390_cpu_restart(S390_CPU(cs))) {
419         error_setg(errp, QERR_UNSUPPORTED);
420     }
421 }
422 
423 static void ccw_machine_class_init(ObjectClass *oc, void *data)
424 {
425     MachineClass *mc = MACHINE_CLASS(oc);
426     NMIClass *nc = NMI_CLASS(oc);
427     HotplugHandlerClass *hc = HOTPLUG_HANDLER_CLASS(oc);
428     S390CcwMachineClass *s390mc = S390_MACHINE_CLASS(mc);
429 
430     s390mc->ri_allowed = true;
431     s390mc->cpu_model_allowed = true;
432     s390mc->css_migration_enabled = true;
433     s390mc->gs_allowed = true;
434     mc->init = ccw_init;
435     mc->reset = s390_machine_reset;
436     mc->hot_add_cpu = s390_hot_add_cpu;
437     mc->block_default_type = IF_VIRTIO;
438     mc->no_cdrom = 1;
439     mc->no_floppy = 1;
440     mc->no_serial = 1;
441     mc->no_parallel = 1;
442     mc->no_sdcard = 1;
443     mc->use_sclp = 1;
444     mc->max_cpus = 248;
445     mc->has_hotpluggable_cpus = true;
446     mc->get_hotplug_handler = s390_get_hotplug_handler;
447     mc->cpu_index_to_instance_props = s390_cpu_index_to_props;
448     mc->possible_cpu_arch_ids = s390_possible_cpu_arch_ids;
449     hc->plug = s390_machine_device_plug;
450     hc->unplug_request = s390_machine_device_unplug_request;
451     nc->nmi_monitor_handler = s390_nmi;
452 }
453 
454 static inline bool machine_get_aes_key_wrap(Object *obj, Error **errp)
455 {
456     S390CcwMachineState *ms = S390_CCW_MACHINE(obj);
457 
458     return ms->aes_key_wrap;
459 }
460 
461 static inline void machine_set_aes_key_wrap(Object *obj, bool value,
462                                             Error **errp)
463 {
464     S390CcwMachineState *ms = S390_CCW_MACHINE(obj);
465 
466     ms->aes_key_wrap = value;
467 }
468 
469 static inline bool machine_get_dea_key_wrap(Object *obj, Error **errp)
470 {
471     S390CcwMachineState *ms = S390_CCW_MACHINE(obj);
472 
473     return ms->dea_key_wrap;
474 }
475 
476 static inline void machine_set_dea_key_wrap(Object *obj, bool value,
477                                             Error **errp)
478 {
479     S390CcwMachineState *ms = S390_CCW_MACHINE(obj);
480 
481     ms->dea_key_wrap = value;
482 }
483 
484 static S390CcwMachineClass *current_mc;
485 
486 static S390CcwMachineClass *get_machine_class(void)
487 {
488     if (unlikely(!current_mc)) {
489         /*
490         * No s390 ccw machine was instantiated, we are likely to
491         * be called for the 'none' machine. The properties will
492         * have their after-initialization values.
493         */
494         current_mc = S390_MACHINE_CLASS(
495                      object_class_by_name(TYPE_S390_CCW_MACHINE));
496     }
497     return current_mc;
498 }
499 
500 bool ri_allowed(void)
501 {
502     /* for "none" machine this results in true */
503     return get_machine_class()->ri_allowed;
504 }
505 
506 bool cpu_model_allowed(void)
507 {
508     /* for "none" machine this results in true */
509     return get_machine_class()->cpu_model_allowed;
510 }
511 
512 bool gs_allowed(void)
513 {
514     /* for "none" machine this results in true */
515     return get_machine_class()->gs_allowed;
516 }
517 
518 static char *machine_get_loadparm(Object *obj, Error **errp)
519 {
520     S390CcwMachineState *ms = S390_CCW_MACHINE(obj);
521 
522     return g_memdup(ms->loadparm, sizeof(ms->loadparm));
523 }
524 
525 static void machine_set_loadparm(Object *obj, const char *val, Error **errp)
526 {
527     S390CcwMachineState *ms = S390_CCW_MACHINE(obj);
528     int i;
529 
530     for (i = 0; i < sizeof(ms->loadparm) && val[i]; i++) {
531         uint8_t c = qemu_toupper(val[i]); /* mimic HMC */
532 
533         if (('A' <= c && c <= 'Z') || ('0' <= c && c <= '9') || (c == '.') ||
534             (c == ' ')) {
535             ms->loadparm[i] = c;
536         } else {
537             error_setg(errp, "LOADPARM: invalid character '%c' (ASCII 0x%02x)",
538                        c, c);
539             return;
540         }
541     }
542 
543     for (; i < sizeof(ms->loadparm); i++) {
544         ms->loadparm[i] = ' '; /* pad right with spaces */
545     }
546 }
547 static inline bool machine_get_squash_mcss(Object *obj, Error **errp)
548 {
549     S390CcwMachineState *ms = S390_CCW_MACHINE(obj);
550 
551     return ms->s390_squash_mcss;
552 }
553 
554 static inline void machine_set_squash_mcss(Object *obj, bool value,
555                                            Error **errp)
556 {
557     S390CcwMachineState *ms = S390_CCW_MACHINE(obj);
558 
559     ms->s390_squash_mcss = value;
560 }
561 
562 static inline void s390_machine_initfn(Object *obj)
563 {
564     object_property_add_bool(obj, "aes-key-wrap",
565                              machine_get_aes_key_wrap,
566                              machine_set_aes_key_wrap, NULL);
567     object_property_set_description(obj, "aes-key-wrap",
568             "enable/disable AES key wrapping using the CPACF wrapping key",
569             NULL);
570     object_property_set_bool(obj, true, "aes-key-wrap", NULL);
571 
572     object_property_add_bool(obj, "dea-key-wrap",
573                              machine_get_dea_key_wrap,
574                              machine_set_dea_key_wrap, NULL);
575     object_property_set_description(obj, "dea-key-wrap",
576             "enable/disable DEA key wrapping using the CPACF wrapping key",
577             NULL);
578     object_property_set_bool(obj, true, "dea-key-wrap", NULL);
579     object_property_add_str(obj, "loadparm",
580             machine_get_loadparm, machine_set_loadparm, NULL);
581     object_property_set_description(obj, "loadparm",
582             "Up to 8 chars in set of [A-Za-z0-9. ] (lower case chars converted"
583             " to upper case) to pass to machine loader, boot manager,"
584             " and guest kernel",
585             NULL);
586     object_property_add_bool(obj, "s390-squash-mcss",
587                              machine_get_squash_mcss,
588                              machine_set_squash_mcss, NULL);
589     object_property_set_description(obj, "s390-squash-mcss",
590             "enable/disable squashing subchannels into the default css",
591             NULL);
592     object_property_set_bool(obj, false, "s390-squash-mcss", NULL);
593 }
594 
595 static const TypeInfo ccw_machine_info = {
596     .name          = TYPE_S390_CCW_MACHINE,
597     .parent        = TYPE_MACHINE,
598     .abstract      = true,
599     .instance_size = sizeof(S390CcwMachineState),
600     .instance_init = s390_machine_initfn,
601     .class_size = sizeof(S390CcwMachineClass),
602     .class_init    = ccw_machine_class_init,
603     .interfaces = (InterfaceInfo[]) {
604         { TYPE_NMI },
605         { TYPE_HOTPLUG_HANDLER},
606         { }
607     },
608 };
609 
610 bool css_migration_enabled(void)
611 {
612     return get_machine_class()->css_migration_enabled;
613 }
614 
615 #define DEFINE_CCW_MACHINE(suffix, verstr, latest)                            \
616     static void ccw_machine_##suffix##_class_init(ObjectClass *oc,            \
617                                                   void *data)                 \
618     {                                                                         \
619         MachineClass *mc = MACHINE_CLASS(oc);                                 \
620         ccw_machine_##suffix##_class_options(mc);                             \
621         mc->desc = "VirtIO-ccw based S390 machine v" verstr;                  \
622         if (latest) {                                                         \
623             mc->alias = "s390-ccw-virtio";                                    \
624             mc->is_default = 1;                                               \
625         }                                                                     \
626     }                                                                         \
627     static void ccw_machine_##suffix##_instance_init(Object *obj)             \
628     {                                                                         \
629         MachineState *machine = MACHINE(obj);                                 \
630         current_mc = S390_MACHINE_CLASS(MACHINE_GET_CLASS(machine));          \
631         ccw_machine_##suffix##_instance_options(machine);                     \
632     }                                                                         \
633     static const TypeInfo ccw_machine_##suffix##_info = {                     \
634         .name = MACHINE_TYPE_NAME("s390-ccw-virtio-" verstr),                 \
635         .parent = TYPE_S390_CCW_MACHINE,                                      \
636         .class_init = ccw_machine_##suffix##_class_init,                      \
637         .instance_init = ccw_machine_##suffix##_instance_init,                \
638     };                                                                        \
639     static void ccw_machine_register_##suffix(void)                           \
640     {                                                                         \
641         type_register_static(&ccw_machine_##suffix##_info);                   \
642     }                                                                         \
643     type_init(ccw_machine_register_##suffix)
644 
645 #define CCW_COMPAT_2_10 \
646         HW_COMPAT_2_10
647 
648 #define CCW_COMPAT_2_9 \
649         HW_COMPAT_2_9 \
650         {\
651             .driver   = TYPE_S390_STATTRIB,\
652             .property = "migration-enabled",\
653             .value    = "off",\
654         },
655 
656 #define CCW_COMPAT_2_8 \
657         HW_COMPAT_2_8 \
658         {\
659             .driver   = TYPE_S390_FLIC_COMMON,\
660             .property = "adapter_routes_max_batch",\
661             .value    = "64",\
662         },
663 
664 #define CCW_COMPAT_2_7 \
665         HW_COMPAT_2_7
666 
667 #define CCW_COMPAT_2_6 \
668         HW_COMPAT_2_6 \
669         {\
670             .driver   = TYPE_S390_IPL,\
671             .property = "iplbext_migration",\
672             .value    = "off",\
673         }, {\
674             .driver   = TYPE_VIRTUAL_CSS_BRIDGE,\
675             .property = "css_dev_path",\
676             .value    = "off",\
677         },
678 
679 #define CCW_COMPAT_2_5 \
680         HW_COMPAT_2_5
681 
682 #define CCW_COMPAT_2_4 \
683         HW_COMPAT_2_4 \
684         {\
685             .driver   = TYPE_S390_SKEYS,\
686             .property = "migration-enabled",\
687             .value    = "off",\
688         },{\
689             .driver   = "virtio-blk-ccw",\
690             .property = "max_revision",\
691             .value    = "0",\
692         },{\
693             .driver   = "virtio-balloon-ccw",\
694             .property = "max_revision",\
695             .value    = "0",\
696         },{\
697             .driver   = "virtio-serial-ccw",\
698             .property = "max_revision",\
699             .value    = "0",\
700         },{\
701             .driver   = "virtio-9p-ccw",\
702             .property = "max_revision",\
703             .value    = "0",\
704         },{\
705             .driver   = "virtio-rng-ccw",\
706             .property = "max_revision",\
707             .value    = "0",\
708         },{\
709             .driver   = "virtio-net-ccw",\
710             .property = "max_revision",\
711             .value    = "0",\
712         },{\
713             .driver   = "virtio-scsi-ccw",\
714             .property = "max_revision",\
715             .value    = "0",\
716         },{\
717             .driver   = "vhost-scsi-ccw",\
718             .property = "max_revision",\
719             .value    = "0",\
720         },
721 
722 static void ccw_machine_2_11_instance_options(MachineState *machine)
723 {
724 }
725 
726 static void ccw_machine_2_11_class_options(MachineClass *mc)
727 {
728 }
729 DEFINE_CCW_MACHINE(2_11, "2.11", true);
730 
731 static void ccw_machine_2_10_instance_options(MachineState *machine)
732 {
733     ccw_machine_2_11_instance_options(machine);
734     if (css_migration_enabled()) {
735         css_register_vmstate();
736     }
737 }
738 
739 static void ccw_machine_2_10_class_options(MachineClass *mc)
740 {
741     ccw_machine_2_11_class_options(mc);
742     SET_MACHINE_COMPAT(mc, CCW_COMPAT_2_10);
743 }
744 DEFINE_CCW_MACHINE(2_10, "2.10", false);
745 
746 static void ccw_machine_2_9_instance_options(MachineState *machine)
747 {
748     ccw_machine_2_10_instance_options(machine);
749     s390_cpudef_featoff_greater(12, 1, S390_FEAT_ESOP);
750     s390_cpudef_featoff_greater(12, 1, S390_FEAT_SIDE_EFFECT_ACCESS_ESOP2);
751     s390_cpudef_featoff_greater(12, 1, S390_FEAT_ZPCI);
752     s390_cpudef_featoff_greater(12, 1, S390_FEAT_ADAPTER_INT_SUPPRESSION);
753     s390_cpudef_featoff_greater(12, 1, S390_FEAT_ADAPTER_EVENT_NOTIFICATION);
754 }
755 
756 static void ccw_machine_2_9_class_options(MachineClass *mc)
757 {
758     S390CcwMachineClass *s390mc = S390_MACHINE_CLASS(mc);
759 
760     s390mc->gs_allowed = false;
761     ccw_machine_2_10_class_options(mc);
762     SET_MACHINE_COMPAT(mc, CCW_COMPAT_2_9);
763     s390mc->css_migration_enabled = false;
764 }
765 DEFINE_CCW_MACHINE(2_9, "2.9", false);
766 
767 static void ccw_machine_2_8_instance_options(MachineState *machine)
768 {
769     ccw_machine_2_9_instance_options(machine);
770 }
771 
772 static void ccw_machine_2_8_class_options(MachineClass *mc)
773 {
774     ccw_machine_2_9_class_options(mc);
775     SET_MACHINE_COMPAT(mc, CCW_COMPAT_2_8);
776 }
777 DEFINE_CCW_MACHINE(2_8, "2.8", false);
778 
779 static void ccw_machine_2_7_instance_options(MachineState *machine)
780 {
781     ccw_machine_2_8_instance_options(machine);
782 }
783 
784 static void ccw_machine_2_7_class_options(MachineClass *mc)
785 {
786     S390CcwMachineClass *s390mc = S390_MACHINE_CLASS(mc);
787 
788     s390mc->cpu_model_allowed = false;
789     ccw_machine_2_8_class_options(mc);
790     SET_MACHINE_COMPAT(mc, CCW_COMPAT_2_7);
791 }
792 DEFINE_CCW_MACHINE(2_7, "2.7", false);
793 
794 static void ccw_machine_2_6_instance_options(MachineState *machine)
795 {
796     ccw_machine_2_7_instance_options(machine);
797 }
798 
799 static void ccw_machine_2_6_class_options(MachineClass *mc)
800 {
801     S390CcwMachineClass *s390mc = S390_MACHINE_CLASS(mc);
802 
803     s390mc->ri_allowed = false;
804     ccw_machine_2_7_class_options(mc);
805     SET_MACHINE_COMPAT(mc, CCW_COMPAT_2_6);
806 }
807 DEFINE_CCW_MACHINE(2_6, "2.6", false);
808 
809 static void ccw_machine_2_5_instance_options(MachineState *machine)
810 {
811     ccw_machine_2_6_instance_options(machine);
812 }
813 
814 static void ccw_machine_2_5_class_options(MachineClass *mc)
815 {
816     ccw_machine_2_6_class_options(mc);
817     SET_MACHINE_COMPAT(mc, CCW_COMPAT_2_5);
818 }
819 DEFINE_CCW_MACHINE(2_5, "2.5", false);
820 
821 static void ccw_machine_2_4_instance_options(MachineState *machine)
822 {
823     ccw_machine_2_5_instance_options(machine);
824 }
825 
826 static void ccw_machine_2_4_class_options(MachineClass *mc)
827 {
828     ccw_machine_2_5_class_options(mc);
829     SET_MACHINE_COMPAT(mc, CCW_COMPAT_2_4);
830 }
831 DEFINE_CCW_MACHINE(2_4, "2.4", false);
832 
833 static void ccw_machine_register_types(void)
834 {
835     type_register_static(&ccw_machine_info);
836 }
837 
838 type_init(ccw_machine_register_types)
839