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