blob: 7262725d2e8a1cc1fa33fdbe2a074c87dfe69628 [file] [log] [blame]
Cornelia Hucka5c95802013-01-24 06:08:56 +00001/*
2 * virtio ccw machine
3 *
Janosch Frankc3347ed2020-03-23 04:36:06 -04004 * Copyright 2012, 2020 IBM Corp.
David Hildenbrand6286b412017-09-13 15:23:58 +02005 * Copyright (c) 2009 Alexander Graf <agraf@suse.de>
Cornelia Hucka5c95802013-01-24 06:08:56 +00006 * Author(s): Cornelia Huck <cornelia.huck@de.ibm.com>
Janosch Frankc3347ed2020-03-23 04:36:06 -04007 * Janosch Frank <frankja@linux.ibm.com>
Cornelia Hucka5c95802013-01-24 06:08:56 +00008 *
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
Peter Maydell96154952016-01-26 18:17:00 +000014#include "qemu/osdep.h"
Markus Armbrusterda34e652016-03-14 09:01:28 +010015#include "qapi/error.h"
David Hildenbrand91389772019-04-17 13:31:42 +020016#include "exec/ram_addr.h"
David Hildenbrand7d577542017-09-13 15:23:59 +020017#include "hw/s390x/s390-virtio-hcall.h"
Paolo Bonzini83c9f4c2013-02-04 15:40:22 +010018#include "hw/s390x/sclp.h"
Jens Freimann3a553fc2013-07-16 09:04:04 +020019#include "hw/s390x/s390_flic.h"
Paolo Bonzinibd3f16a2015-12-04 12:06:26 +010020#include "hw/s390x/ioinst.h"
21#include "hw/s390x/css.h"
Cornelia Hucka5c95802013-01-24 06:08:56 +000022#include "virtio-ccw.h"
Matthew Rosatob6fe0122014-08-28 11:25:33 -040023#include "qemu/config-file.h"
Markus Armbruster856dfd82019-05-23 16:35:06 +020024#include "qemu/ctype.h"
David Hildenbrandb5684cd2017-09-13 15:24:06 +020025#include "qemu/error-report.h"
Markus Armbruster922a01a2018-02-01 12:18:46 +010026#include "qemu/option.h"
Christian Borntraeger5c30ef92020-04-01 08:37:54 -040027#include "qemu/qemu-print.h"
Paolo Bonzinia43de792022-03-28 13:41:29 +020028#include "qemu/units.h"
Matthew Rosato408b55d2020-10-26 11:34:31 -040029#include "hw/s390x/s390-pci-bus.h"
Markus Armbruster71e8a912019-08-12 07:23:38 +020030#include "sysemu/reset.h"
Jason J. Herne0f5f6692015-06-26 14:01:00 -040031#include "hw/s390x/storage-keys.h"
Claudio Imbrenda903fd802016-08-15 18:43:14 +020032#include "hw/s390x/storage-attributes.h"
Claudio Imbrendabc61c8c2018-02-23 18:42:56 +010033#include "hw/s390x/event-facility.h"
Alexander Yarygin04ca4b92015-07-13 15:04:36 +030034#include "ipl.h"
Janosch Frank8b8a61a2016-03-07 09:04:21 +010035#include "hw/s390x/s390-virtio-ccw.h"
Jing Liudd70bd02015-11-06 12:32:40 +010036#include "hw/s390x/css-bridge.h"
Tony Krowiaka51b3152018-10-10 13:03:06 -040037#include "hw/s390x/ap-bridge.h"
Juan Quintelaf2a8f0a2017-04-24 13:42:55 +020038#include "migration/register.h"
Jason J. Herne7223bcc2017-04-10 09:39:00 -040039#include "cpu_models.h"
David Hildenbrand6286b412017-09-13 15:23:58 +020040#include "hw/nmi.h"
Markus Armbrustera27bd6c2019-08-12 07:23:51 +020041#include "hw/qdev-properties.h"
David Hildenbrand8046f372018-06-27 15:44:04 +020042#include "hw/s390x/tod.h"
Markus Armbruster2f780b62019-08-12 07:23:58 +020043#include "sysemu/sysemu.h"
Claudio Imbrendac3a073c2023-02-14 17:30:35 +010044#include "sysemu/cpus.h"
Philippe Mathieu-Daudéf5f9c6e2023-06-24 22:06:44 +020045#include "target/s390x/kvm/pv.h"
Janosch Frank0141e1b2020-03-19 09:19:09 -040046#include "migration/blocker.h"
Pierre Morel1fd396e2022-11-03 18:01:40 +010047#include "qapi/visitor.h"
Pierre Morelc809bbc2023-10-16 20:39:07 +020048#include "hw/s390x/cpu-topology.h"
Janosch Frank0141e1b2020-03-19 09:19:09 -040049
50static Error *pv_mig_blocker;
David Hildenbrand6286b412017-09-13 15:23:58 +020051
David Hildenbrand6286b412017-09-13 15:23:58 +020052S390CPU *s390_cpu_addr2state(uint16_t cpu_addr)
53{
David Hildenbrand2b441782017-09-13 15:24:14 +020054 static MachineState *ms;
55
56 if (!ms) {
57 ms = MACHINE(qdev_get_machine());
58 g_assert(ms->possible_cpus);
David Hildenbrand6286b412017-09-13 15:23:58 +020059 }
60
David Hildenbrand2b441782017-09-13 15:24:14 +020061 /* 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);
David Hildenbrand6286b412017-09-13 15:23:58 +020066}
67
Igor Mammedov32dc6aa2017-10-17 17:13:23 +020068static S390CPU *s390x_new_cpu(const char *typename, uint32_t core_id,
69 Error **errp)
70{
71 S390CPU *cpu = S390_CPU(object_new(typename));
Markus Armbrusterf07ad482020-07-07 18:05:57 +020072 S390CPU *ret = NULL;
Igor Mammedov32dc6aa2017-10-17 17:13:23 +020073
Markus Armbruster992861f2020-07-07 18:06:04 +020074 if (!object_property_set_int(OBJECT(cpu), "core-id", core_id, errp)) {
Igor Mammedov32dc6aa2017-10-17 17:13:23 +020075 goto out;
76 }
Markus Armbruster992861f2020-07-07 18:06:04 +020077 if (!qdev_realize(DEVICE(cpu), NULL, errp)) {
Markus Armbrusterf07ad482020-07-07 18:05:57 +020078 goto out;
79 }
80 ret = cpu;
Igor Mammedov32dc6aa2017-10-17 17:13:23 +020081
82out:
83 object_unref(OBJECT(cpu));
Markus Armbrusterf07ad482020-07-07 18:05:57 +020084 return ret;
Igor Mammedov32dc6aa2017-10-17 17:13:23 +020085}
86
David Hildenbrand6286b412017-09-13 15:23:58 +020087static void s390_init_cpus(MachineState *machine)
88{
David Hildenbrand4dc3b152017-09-13 15:24:13 +020089 MachineClass *mc = MACHINE_GET_CLASS(machine);
Pierre Morel6393b292022-11-03 18:01:41 +010090 S390CcwMachineClass *s390mc = S390_CCW_MACHINE_CLASS(mc);
David Hildenbrand6286b412017-09-13 15:23:58 +020091 int i;
David Hildenbrand6286b412017-09-13 15:23:58 +020092
Pierre Morel6393b292022-11-03 18:01:41 +010093 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
David Hildenbrand4dc3b152017-09-13 15:24:13 +020099 /* initialize possible_cpus */
100 mc->possible_cpu_arch_ids(machine);
101
Like Xuae71ed82019-05-19 04:54:24 +0800102 for (i = 0; i < machine->smp.cpus; i++) {
Igor Mammedovb6805e12017-09-21 14:59:08 +0200103 s390x_new_cpu(machine->cpu_type, i, &error_fatal);
David Hildenbrand6286b412017-09-13 15:23:58 +0200104 }
105}
Tony Krowiak2eb1cd02015-03-12 13:53:51 +0100106
David Hildenbrand09c7f582015-07-21 10:58:38 +0200107static const char *const reset_dev_types[] = {
Sascha Silbe3f9e4852016-07-04 15:46:20 +0200108 TYPE_VIRTUAL_CSS_BRIDGE,
David Hildenbrand09c7f582015-07-21 10:58:38 +0200109 "s390-sclp-event-facility",
110 "s390-flic",
111 "diag288",
Matthew Rosatodb082442020-10-15 09:16:07 -0400112 TYPE_S390_PCI_HOST_BRIDGE,
Janosch Frank297ec012023-08-23 16:22:15 +0200113 TYPE_AP_BRIDGE,
David Hildenbrand09c7f582015-07-21 10:58:38 +0200114};
115
David Hildenbranda30fb812018-04-24 12:18:59 +0200116static void subsystem_reset(void)
Christian Borntraeger4e872a32013-07-25 16:37:37 +0200117{
David Hildenbrand09c7f582015-07-21 10:58:38 +0200118 DeviceState *dev;
119 int i;
Christian Borntraeger4e872a32013-07-25 16:37:37 +0200120
David Hildenbrand09c7f582015-07-21 10:58:38 +0200121 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) {
Peter Maydelldfa6ba62022-12-16 15:55:27 +0000124 device_cold_reset(dev);
David Hildenbrand09c7f582015-07-21 10:58:38 +0200125 }
Xu Wang0c7322c2015-06-29 08:21:10 +0200126 }
Pierre Morel3d6e75f2023-10-16 20:39:10 +0200127 if (s390_has_topology()) {
128 s390_topology_reset();
129 }
Christian Borntraeger4e872a32013-07-25 16:37:37 +0200130}
131
Cornelia Hucka5c95802013-01-24 06:08:56 +0000132static 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 }
Halil Pasicb1914b82015-12-07 16:45:17 +0100146 if (queue >= VIRTIO_QUEUE_MAX) {
Cornelia Huckb57ed9b2013-03-26 17:32:44 +0100147 return -EINVAL;
148 }
Cornelia Hucka5c95802013-01-24 06:08:56 +0000149 virtio_queue_notify(virtio_ccw_get_vdev(sch), queue);
150 return 0;
151
152}
153
154static int virtio_ccw_hcall_early_printk(const uint64_t *args)
155{
156 uint64_t mem = args[0];
Paolo Bonzini382a04a2020-10-28 06:17:07 -0400157 MachineState *ms = MACHINE(qdev_get_machine());
Cornelia Hucka5c95802013-01-24 06:08:56 +0000158
Paolo Bonzini382a04a2020-10-28 06:17:07 -0400159 if (mem < ms->ram_size) {
Cornelia Hucka5c95802013-01-24 06:08:56 +0000160 /* Early printk */
161 return 0;
162 }
163 return -EINVAL;
164}
165
166static 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
Igor Mammedov3a12fc62020-02-19 11:09:12 -0500175static void s390_memory_init(MemoryRegion *ram)
Cornelia Hucka5c95802013-01-24 06:08:56 +0000176{
Cornelia Hucka5c95802013-01-24 06:08:56 +0000177 MemoryRegion *sysmem = get_system_memory();
David Hildenbrand80d23272015-05-29 15:01:55 +0200178
179 /* allocate RAM for core */
Igor Mammedovfb1fc5a2019-09-24 10:47:51 -0400180 memory_region_add_subregion(sysmem, 0, ram);
David Hildenbrand80d23272015-05-29 15:01:55 +0200181
David Hildenbrand91389772019-04-17 13:31:42 +0200182 /*
183 * Configure the maximum page size. As no memory devices were created
184 * yet, this is the page size of initial memory only.
185 */
Markus Armbruster805d4492020-07-22 10:40:48 +0200186 s390_set_max_pagesize(qemu_maxrampagesize(), &error_fatal);
David Hildenbrand80d23272015-05-29 15:01:55 +0200187 /* Initialize storage key device */
188 s390_skeys_init();
Claudio Imbrenda903fd802016-08-15 18:43:14 +0200189 /* Initialize storage attributes device */
190 s390_stattrib_init();
David Hildenbrand80d23272015-05-29 15:01:55 +0200191}
192
David Hildenbrand6286b412017-09-13 15:23:58 +0200193static 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);
Greg Kurzd9b06db2018-03-29 11:10:06 +0200200 char *netboot_fw_prop;
David Hildenbrand6286b412017-09-13 15:23:58 +0200201
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);
David Hildenbrand6286b412017-09-13 15:23:58 +0200210 qdev_prop_set_bit(dev, "enforce_bios", enforce_bios);
Greg Kurzd9b06db2018-03-29 11:10:06 +0200211 netboot_fw_prop = object_property_get_str(new, "netboot_fw", &error_abort);
212 if (!strlen(netboot_fw_prop)) {
Thomas Huth3c4e9ba2018-02-27 12:32:34 +0100213 qdev_prop_set_string(dev, "netboot_fw", netboot_fw);
214 }
Greg Kurzd9b06db2018-03-29 11:10:06 +0200215 g_free(netboot_fw_prop);
David Hildenbrand6286b412017-09-13 15:23:58 +0200216 object_property_add_child(qdev_get_machine(), TYPE_S390_IPL,
Markus Armbrusterd2623122020-05-05 17:29:22 +0200217 new);
David Hildenbrand6286b412017-09-13 15:23:58 +0200218 object_unref(new);
Markus Armbrusterce189ab2020-06-10 07:32:45 +0200219 qdev_realize(dev, NULL, &error_fatal);
David Hildenbrand6286b412017-09-13 15:23:58 +0200220}
221
222static 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
David Hildenbrand6286b412017-09-13 15:23:58 +0200230 qemu_check_nic_model(nd, "virtio");
231
Markus Armbruster3e80f692020-06-10 07:31:58 +0200232 dev = qdev_new(name);
David Hildenbrand6286b412017-09-13 15:23:58 +0200233 qdev_set_nic_properties(dev, nd);
Markus Armbruster3e80f692020-06-10 07:31:58 +0200234 qdev_realize_and_unref(dev, bus, &error_fatal);
David Hildenbrand6286b412017-09-13 15:23:58 +0200235 }
236}
237
Thomas Huth052888f2018-04-26 16:59:54 +0200238static void s390_create_sclpconsole(const char *type, Chardev *chardev)
239{
240 DeviceState *dev;
241
Markus Armbruster3e80f692020-06-10 07:31:58 +0200242 dev = qdev_new(type);
Thomas Huth052888f2018-04-26 16:59:54 +0200243 qdev_prop_set_chr(dev, "chardev", chardev);
Markus Armbruster3e80f692020-06-10 07:31:58 +0200244 qdev_realize_and_unref(dev, sclp_get_event_facility_bus(), &error_fatal);
Thomas Huth052888f2018-04-26 16:59:54 +0200245}
246
David Hildenbrand80d23272015-05-29 15:01:55 +0200247static void ccw_init(MachineState *machine)
248{
Thomas Hutha32b1582023-05-11 14:50:36 +0200249 MachineClass *mc = MACHINE_GET_CLASS(machine);
Cornelia Hucka5c95802013-01-24 06:08:56 +0000250 int ret;
251 VirtualCssBus *css_bus;
Christian Borntraegerc1843e22017-09-28 15:18:31 +0200252 DeviceState *dev;
Cornelia Hucka5c95802013-01-24 06:08:56 +0000253
David Hildenbrand1cf065f2015-05-29 13:53:08 +0200254 s390_sclp_init();
David Hildenbrand91389772019-04-17 13:31:42 +0200255 /* init memory + setup max page size. Required for the CPU model */
Igor Mammedov3a12fc62020-02-19 11:09:12 -0500256 s390_memory_init(machine->ram);
Cornelia Hucka5c95802013-01-24 06:08:56 +0000257
Cornelia Huckd32bd032017-07-06 17:21:52 +0200258 /* init CPUs (incl. CPU model) early so s390_has_feature() works */
Yi Min Zhao3720d332017-06-14 13:16:20 +0800259 s390_init_cpus(machine);
260
David Gibson651615d2020-07-23 14:36:45 +1000261 /* Need CPU model to be determined before we can set up PV */
262 s390_pv_init(machine->cgs, &error_fatal);
263
Fei Lic572d3f2016-12-02 09:37:48 +0100264 s390_flic_init();
265
David Hildenbrand74b4c742017-09-28 22:36:54 +0200266 /* init the SIGP facility */
267 s390_init_sigp();
268
Tony Krowiaka51b3152018-10-10 13:03:06 -0400269 /* create AP bridge and bus(es) */
270 s390_init_ap();
271
Cornelia Hucka5c95802013-01-24 06:08:56 +0000272 /* get a BUS */
273 css_bus = virtual_css_bus_init();
Marcel Apfelbaum3ef96222014-05-07 17:42:57 +0300274 s390_init_ipl_dev(machine->kernel_filename, machine->kernel_cmdline,
Paolo Bonzinif0344392020-10-26 10:30:25 -0400275 machine->initrd_filename,
276 machine->firmware ?: "s390-ccw.img",
Farhan Ali5f31ade2016-10-21 12:17:08 -0400277 "s390-netboot.img", true);
Cornelia Hucka5c95802013-01-24 06:08:56 +0000278
Markus Armbruster3e80f692020-06-10 07:31:58 +0200279 dev = qdev_new(TYPE_S390_PCI_HOST_BRIDGE);
Christian Borntraegerc1843e22017-09-28 15:18:31 +0200280 object_property_add_child(qdev_get_machine(), TYPE_S390_PCI_HOST_BRIDGE,
Markus Armbrusterd2623122020-05-05 17:29:22 +0200281 OBJECT(dev));
Markus Armbruster3c6ef472020-06-10 07:32:34 +0200282 sysbus_realize_and_unref(SYS_BUS_DEVICE(dev), &error_fatal);
Frank Blaschka8cba80c2015-01-09 09:04:38 +0100283
Cornelia Hucka5c95802013-01-24 06:08:56 +0000284 /* register hypercalls */
285 virtio_ccw_register_hcalls();
286
David Hildenbrand5e7164c2017-08-18 13:43:51 +0200287 s390_enable_css_support(s390_cpu_addr2state(0));
Cornelia Huck36699ab2018-07-23 18:32:21 +0200288
289 ret = css_create_css_image(VIRTUAL_CSSID, true);
Halil Pasicd69969e2017-12-06 15:44:38 +0100290
Cornelia Hucka5c95802013-01-24 06:08:56 +0000291 assert(ret == 0);
Halil Pasic489c9092017-10-04 13:01:09 +0200292 if (css_migration_enabled()) {
293 css_register_vmstate();
294 }
Cornelia Hucka5c95802013-01-24 06:08:56 +0000295
296 /* Create VirtIO network adapters */
Thomas Hutha32b1582023-05-11 14:50:36 +0200297 s390_create_virtio_net(BUS(css_bus), mc->default_nic);
Jason J. Herne3f9e59b2015-03-09 15:56:08 +0100298
Thomas Huth052888f2018-04-26 16:59:54 +0200299 /* 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
David Hildenbrand8046f372018-06-27 15:44:04 +0200307 /* init the TOD clock */
308 s390_init_tod();
Cornelia Hucka5c95802013-01-24 06:08:56 +0000309}
310
Matthew Rosato502edbf2016-03-04 12:34:33 -0500311static void s390_cpu_plug(HotplugHandler *hotplug_dev,
312 DeviceState *dev, Error **errp)
313{
David Hildenbrand4dc3b152017-09-13 15:24:13 +0200314 MachineState *ms = MACHINE(hotplug_dev);
Matthew Rosato502edbf2016-03-04 12:34:33 -0500315 S390CPU *cpu = S390_CPU(dev);
Pierre Morelc809bbc2023-10-16 20:39:07 +0200316 ERRP_GUARD();
David Hildenbrand4dc3b152017-09-13 15:24:13 +0200317
318 g_assert(!ms->possible_cpus->cpus[cpu->env.core_id].cpu);
319 ms->possible_cpus->cpus[cpu->env.core_id].cpu = OBJECT(dev);
David Hildenbrandc5b93432017-09-28 15:46:06 +0200320
Pierre Morelc809bbc2023-10-16 20:39:07 +0200321 if (s390_has_topology()) {
322 s390_topology_setup_cpu(ms, cpu, errp);
323 if (*errp) {
324 return;
325 }
326 }
327
David Hildenbrandc5b93432017-09-28 15:46:06 +0200328 if (dev->hotplugged) {
329 raise_irq_cpu_hotplug();
330 }
Matthew Rosato502edbf2016-03-04 12:34:33 -0500331}
332
David Hildenbranda30fb812018-04-24 12:18:59 +0200333static 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
Janosch Frankc3347ed2020-03-23 04:36:06 -0400341static void s390_machine_unprotect(S390CcwMachineState *ms)
342{
Claudio Imbrenda88693ab2023-05-10 12:55:31 +0200343 if (!s390_pv_vm_try_disable_async(ms)) {
Claudio Imbrendac3a073c2023-02-14 17:30:35 +0100344 s390_pv_vm_disable();
345 }
Janosch Frankc3347ed2020-03-23 04:36:06 -0400346 ms->pv = false;
Steve Sistarec8a7fc52023-10-18 06:03:36 -0700347 migrate_del_blocker(&pv_mig_blocker);
David Hildenbrandb0309582020-06-26 09:22:32 +0200348 ram_block_discard_disable(false);
Janosch Frankc3347ed2020-03-23 04:36:06 -0400349}
350
351static int s390_machine_protect(S390CcwMachineState *ms)
352{
Janosch Frank0141e1b2020-03-19 09:19:09 -0400353 Error *local_err = NULL;
Janosch Frankc3347ed2020-03-23 04:36:06 -0400354 int rc;
355
Janosch Frankb1697f62020-03-19 09:19:10 -0400356 /*
David Hildenbrandb0309582020-06-26 09:22:32 +0200357 * 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.
Janosch Frankb1697f62020-03-19 09:19:10 -0400361 */
David Hildenbrandb0309582020-06-26 09:22:32 +0200362 rc = ram_block_discard_disable(true);
363 if (rc) {
364 error_report("protected VMs: cannot disable RAM discard");
365 return rc;
366 }
367
Janosch Frank0141e1b2020-03-19 09:19:09 -0400368 error_setg(&pv_mig_blocker,
Thomas Huth44ee69e2022-11-11 19:17:33 +0100369 "protected VMs are currently not migratable.");
Steve Sistarec8a7fc52023-10-18 06:03:36 -0700370 rc = migrate_add_blocker(&pv_mig_blocker, &local_err);
Janosch Frank0141e1b2020-03-19 09:19:09 -0400371 if (rc) {
David Hildenbrandb0309582020-06-26 09:22:32 +0200372 ram_block_discard_disable(false);
Janosch Frank0141e1b2020-03-19 09:19:09 -0400373 error_report_err(local_err);
Janosch Frank0141e1b2020-03-19 09:19:09 -0400374 return rc;
375 }
376
Janosch Frankc3347ed2020-03-23 04:36:06 -0400377 /* Create SE VM */
378 rc = s390_pv_vm_enable();
379 if (rc) {
David Hildenbrandb0309582020-06-26 09:22:32 +0200380 ram_block_discard_disable(false);
Steve Sistarec8a7fc52023-10-18 06:03:36 -0700381 migrate_del_blocker(&pv_mig_blocker);
Janosch Frankc3347ed2020-03-23 04:36:06 -0400382 return rc;
383 }
384
385 ms->pv = true;
386
Janosch Frank03d83ec2022-10-17 08:38:19 +0000387 /* 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
Janosch Frankc3347ed2020-03-23 04:36:06 -0400393 /* 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
412out_err:
413 s390_machine_unprotect(ms);
414 return rc;
415}
416
Janosch Frankc3347ed2020-03-23 04:36:06 -0400417static 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();
Janosch Frank9a432592020-05-05 08:41:59 -0400429 s390_pv_prep_reset();
Janosch Frankc3347ed2020-03-23 04:36:06 -0400430}
431
Jason A. Donenfeld7966d702022-10-25 02:43:17 +0200432static void s390_machine_reset(MachineState *machine, ShutdownCause reason)
David Hildenbrand6286b412017-09-13 15:23:58 +0200433{
Janosch Frankc3347ed2020-03-23 04:36:06 -0400434 S390CcwMachineState *ms = S390_CCW_MACHINE(machine);
David Hildenbranda30fb812018-04-24 12:18:59 +0200435 enum s390_reset reset_type;
436 CPUState *cs, *t;
Janosch Frankc3347ed2020-03-23 04:36:06 -0400437 S390CPU *cpu;
David Hildenbrand6286b412017-09-13 15:23:58 +0200438
David Hildenbranda30fb812018-04-24 12:18:59 +0200439 /* 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 */
David Hildenbrand6286b412017-09-13 15:23:58 +0200443 s390_cmma_reset();
David Hildenbrand6286b412017-09-13 15:23:58 +0200444
Janosch Frankc3347ed2020-03-23 04:36:06 -0400445 cpu = S390_CPU(cs);
446
David Hildenbranda30fb812018-04-24 12:18:59 +0200447 switch (reset_type) {
448 case S390_RESET_EXTERNAL:
449 case S390_RESET_REIPL:
Janosch Frankef153592023-09-01 11:48:51 +0000450 /*
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();
Janosch Frankc3347ed2020-03-23 04:36:06 -0400456 if (s390_is_pv()) {
457 s390_machine_unprotect(ms);
458 }
459
Janosch Frankef153592023-09-01 11:48:51 +0000460 /*
461 * Device reset includes CPU clear resets so this has to be
462 * done AFTER the unprotect call above.
463 */
Jason A. Donenfeld7966d702022-10-25 02:43:17 +0200464 qemu_devices_reset(reason);
David Hildenbranda30fb812018-04-24 12:18:59 +0200465 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:
Janosch Frankc3347ed2020-03-23 04:36:06 -0400471 /*
Thomas Huth44ee69e2022-11-11 19:17:33 +0100472 * Subsystem reset needs to be done before we unshare memory
Janosch Frankc3347ed2020-03-23 04:36:06 -0400473 * and lose access to VIRTIO structures in guest memory.
474 */
475 subsystem_reset();
476 s390_crypto_reset();
477 s390_pv_prepare_reset(ms);
David Hildenbranda30fb812018-04-24 12:18:59 +0200478 CPU_FOREACH(t) {
479 run_on_cpu(t, s390_do_cpu_full_reset, RUN_ON_CPU_NULL);
480 }
David Hildenbranda30fb812018-04-24 12:18:59 +0200481 run_on_cpu(cs, s390_do_cpu_load_normal, RUN_ON_CPU_NULL);
482 break;
483 case S390_RESET_LOAD_NORMAL:
Janosch Frankc3347ed2020-03-23 04:36:06 -0400484 /*
Thomas Huth44ee69e2022-11-11 19:17:33 +0100485 * Subsystem reset needs to be done before we unshare memory
Janosch Frankc3347ed2020-03-23 04:36:06 -0400486 * and lose access to VIRTIO structures in guest memory.
487 */
488 subsystem_reset();
489 s390_pv_prepare_reset(ms);
David Hildenbranda30fb812018-04-24 12:18:59 +0200490 CPU_FOREACH(t) {
Janosch Frankec922732019-11-27 12:50:41 -0500491 if (t == cs) {
492 continue;
493 }
David Hildenbranda30fb812018-04-24 12:18:59 +0200494 run_on_cpu(t, s390_do_cpu_reset, RUN_ON_CPU_NULL);
495 }
David Hildenbranda30fb812018-04-24 12:18:59 +0200496 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;
Janosch Frankc3347ed2020-03-23 04:36:06 -0400499 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)) {
Christian Borntraegerfbc13842020-04-06 06:01:58 -0400512 s390_pv_inject_reset_error(cs);
Janosch Frankc3347ed2020-03-23 04:36:06 -0400513 /*
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;
David Hildenbranda30fb812018-04-24 12:18:59 +0200523 default:
524 g_assert_not_reached();
525 }
Collin Wallinge2c6cd52020-11-13 17:10:22 -0500526
527 CPU_FOREACH(t) {
528 run_on_cpu(t, s390_do_cpu_set_diag318, RUN_ON_CPU_HOST_ULONG(0));
529 }
David Hildenbranda30fb812018-04-24 12:18:59 +0200530 s390_ipl_clear_reset_request();
David Hildenbrand6286b412017-09-13 15:23:58 +0200531}
532
Matthew Rosato502edbf2016-03-04 12:34:33 -0500533static 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
David Hildenbrandf2f3beb2017-09-13 15:24:12 +0200541static 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
David Hildenbrand81ce6aa2018-02-27 12:02:55 +0100550static CpuInstanceProperties s390_cpu_index_to_props(MachineState *ms,
David Hildenbrand4dc3b152017-09-13 15:24:13 +0200551 unsigned cpu_index)
552{
David Hildenbrand81ce6aa2018-02-27 12:02:55 +0100553 MachineClass *mc = MACHINE_GET_CLASS(ms);
554 const CPUArchIdList *possible_cpus = mc->possible_cpu_arch_ids(ms);
David Hildenbrand4dc3b152017-09-13 15:24:13 +0200555
David Hildenbrand81ce6aa2018-02-27 12:02:55 +0100556 assert(cpu_index < possible_cpus->len);
557 return possible_cpus->cpus[cpu_index].props;
David Hildenbrand4dc3b152017-09-13 15:24:13 +0200558}
559
560static const CPUArchIdList *s390_possible_cpu_arch_ids(MachineState *ms)
561{
562 int i;
Like Xuae71ed82019-05-19 04:54:24 +0800563 unsigned int max_cpus = ms->smp.max_cpus;
David Hildenbrand4dc3b152017-09-13 15:24:13 +0200564
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++) {
Pierre Morelc809bbc2023-10-16 20:39:07 +0200574 CpuInstanceProperties *props = &ms->possible_cpus->cpus[i].props;
575
Igor Mammedovd342eb72018-01-10 16:22:50 +0100576 ms->possible_cpus->cpus[i].type = ms->cpu_type;
David Hildenbrand4dc3b152017-09-13 15:24:13 +0200577 ms->possible_cpus->cpus[i].vcpus_count = 1;
578 ms->possible_cpus->cpus[i].arch_id = i;
Pierre Morelc809bbc2023-10-16 20:39:07 +0200579
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);
David Hildenbrand4dc3b152017-09-13 15:24:13 +0200588 }
589
590 return ms->possible_cpus;
591}
592
Matthew Rosato502edbf2016-03-04 12:34:33 -0500593static 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
David Hildenbrand6286b412017-09-13 15:23:58 +0200602static void s390_nmi(NMIState *n, int cpu_index, Error **errp)
603{
604 CPUState *cs = qemu_get_cpu(cpu_index);
605
David Hildenbrand0fc60ca2017-09-28 22:37:06 +0200606 s390_cpu_restart(S390_CPU(cs));
David Hildenbrand6286b412017-09-13 15:23:58 +0200607}
608
Christian Borntraeger5c30ef92020-04-01 08:37:54 -0400609static 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
Tony Krowiak2eb1cd02015-03-12 13:53:51 +0100629static 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
636static 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
644static 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
651static 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
Halil Pasiccec8bbf2017-07-11 16:54:36 +0200659static S390CcwMachineClass *current_mc;
660
Thomas Huth3e0209b2020-01-23 18:02:56 +0100661/*
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 */
Halil Pasiccec8bbf2017-07-11 16:54:36 +0200674static 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 */
Eduardo Habkostb1af5872020-08-25 15:20:44 -0400682 current_mc = S390_CCW_MACHINE_CLASS(
Halil Pasiccec8bbf2017-07-11 16:54:36 +0200683 object_class_by_name(TYPE_S390_CCW_MACHINE));
684 }
685 return current_mc;
686}
687
Fan Zhang97002302016-03-09 13:11:17 +0100688bool ri_allowed(void)
689{
Halil Pasiccec8bbf2017-07-11 16:54:36 +0200690 return get_machine_class()->ri_allowed;
Fan Zhang97002302016-03-09 13:11:17 +0100691}
692
Christian Borntraegere73316d2016-09-07 12:50:40 +0200693bool cpu_model_allowed(void)
694{
Halil Pasiccec8bbf2017-07-11 16:54:36 +0200695 return get_machine_class()->cpu_model_allowed;
Christian Borntraegere73316d2016-09-07 12:50:40 +0200696}
697
Janosch Frank28221f92018-09-28 11:34:35 +0200698bool hpage_1m_allowed(void)
699{
Janosch Frank28221f92018-09-28 11:34:35 +0200700 return get_machine_class()->hpage_1m_allowed;
701}
702
Pierre Morel1fd396e2022-11-03 18:01:40 +0100703static void machine_get_loadparm(Object *obj, Visitor *v,
704 const char *name, void *opaque,
705 Error **errp)
Farhan Ali7104bae2016-03-29 16:18:47 +0200706{
707 S390CcwMachineState *ms = S390_CCW_MACHINE(obj);
Pierre Morel1fd396e2022-11-03 18:01:40 +0100708 char *str = g_strndup((char *) ms->loadparm, sizeof(ms->loadparm));
Farhan Ali7104bae2016-03-29 16:18:47 +0200709
Pierre Morel1fd396e2022-11-03 18:01:40 +0100710 visit_type_str(v, name, &str, errp);
711 g_free(str);
Farhan Ali7104bae2016-03-29 16:18:47 +0200712}
713
Pierre Morel1fd396e2022-11-03 18:01:40 +0100714static void machine_set_loadparm(Object *obj, Visitor *v,
715 const char *name, void *opaque,
716 Error **errp)
Farhan Ali7104bae2016-03-29 16:18:47 +0200717{
718 S390CcwMachineState *ms = S390_CCW_MACHINE(obj);
Pierre Morel1fd396e2022-11-03 18:01:40 +0100719 char *val;
Farhan Ali7104bae2016-03-29 16:18:47 +0200720 int i;
721
Pierre Morel1fd396e2022-11-03 18:01:40 +0100722 if (!visit_type_str(v, name, &val, errp)) {
723 return;
724 }
725
Farhan Ali7104bae2016-03-29 16:18:47 +0200726 for (i = 0; i < sizeof(ms->loadparm) && val[i]; i++) {
Peter Maydell95a5bef2017-07-20 17:31:30 +0100727 uint8_t c = qemu_toupper(val[i]); /* mimic HMC */
Farhan Ali7104bae2016-03-29 16:18:47 +0200728
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}
Tony Krowiak2eb1cd02015-03-12 13:53:51 +0100743
Pierre Morel1fd396e2022-11-03 18:01:40 +0100744static 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;
Pierre Morel6393b292022-11-03 18:01:41 +0100755 s390mc->max_threads = 1;
Pierre Morel1fd396e2022-11-03 18:01:40 +0100756 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;
Pierre Morel5de1aff2023-10-16 20:39:06 +0200765 mc->smp_props.books_supported = true;
766 mc->smp_props.drawers_supported = true;
Pierre Morel1fd396e2022-11-03 18:01:40 +0100767 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";
Thomas Hutha32b1582023-05-11 14:50:36 +0200777 mc->default_nic = "virtio-net-ccw";
Pierre Morel1fd396e2022-11-03 18:01:40 +0100778
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",
Markus Armbruster7eecec72020-05-05 17:29:15 +0200789 "enable/disable DEA key wrapping using the CPACF wrapping key");
Pierre Morel1fd396e2022-11-03 18:01:40 +0100790
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",
Farhan Ali7104bae2016-03-29 16:18:47 +0200795 "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,"
Markus Armbruster7eecec72020-05-05 17:29:15 +0200797 " and guest kernel");
Pierre Morel1fd396e2022-11-03 18:01:40 +0100798}
799
800static 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;
Tony Krowiak2eb1cd02015-03-12 13:53:51 +0100806}
807
Alexey Kardashevskiyd07aa7c2014-08-20 22:16:34 +1000808static const TypeInfo ccw_machine_info = {
809 .name = TYPE_S390_CCW_MACHINE,
810 .parent = TYPE_MACHINE,
Christian Borntraegerc4d3c0a2015-07-01 11:16:57 +0200811 .abstract = true,
Tony Krowiak2eb1cd02015-03-12 13:53:51 +0100812 .instance_size = sizeof(S390CcwMachineState),
813 .instance_init = s390_machine_initfn,
Fan Zhang97002302016-03-09 13:11:17 +0100814 .class_size = sizeof(S390CcwMachineClass),
Alexey Kardashevskiyd07aa7c2014-08-20 22:16:34 +1000815 .class_init = ccw_machine_class_init,
Alexey Kardashevskiy3dd78522014-08-20 22:16:35 +1000816 .interfaces = (InterfaceInfo[]) {
817 { TYPE_NMI },
Matthew Rosato502edbf2016-03-04 12:34:33 -0500818 { TYPE_HOTPLUG_HANDLER},
Alexey Kardashevskiy3dd78522014-08-20 22:16:35 +1000819 { }
820 },
Alexey Kardashevskiyd07aa7c2014-08-20 22:16:34 +1000821};
822
Halil Pasic52629b32017-07-11 16:54:37 +0200823bool css_migration_enabled(void)
824{
825 return get_machine_class()->css_migration_enabled;
826}
827
Janosch Frank4fca6542016-03-03 12:48:34 +0100828#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); \
Thomas Huthec8c2932022-05-06 08:50:26 +0200834 mc->desc = "Virtual s390x machine (version " verstr ")"; \
Janosch Frank4fca6542016-03-03 12:48:34 +0100835 if (latest) { \
836 mc->alias = "s390-ccw-virtio"; \
Philippe Mathieu-Daudéea0ac7f2020-02-07 17:19:47 +0100837 mc->is_default = true; \
Janosch Frank4fca6542016-03-03 12:48:34 +0100838 } \
839 } \
840 static void ccw_machine_##suffix##_instance_init(Object *obj) \
841 { \
842 MachineState *machine = MACHINE(obj); \
Eduardo Habkostb1af5872020-08-25 15:20:44 -0400843 current_mc = S390_CCW_MACHINE_CLASS(MACHINE_GET_CLASS(machine)); \
Janosch Frank4fca6542016-03-03 12:48:34 +0100844 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 } \
Eduardo Habkost0e6aac82016-02-16 18:59:04 -0200856 type_init(ccw_machine_register_##suffix)
Janosch Frank4fca6542016-03-03 12:48:34 +0100857
Cornelia Huck95f5c892023-07-18 16:22:35 +0200858static void ccw_machine_8_2_instance_options(MachineState *machine)
859{
860}
861
862static void ccw_machine_8_2_class_options(MachineClass *mc)
863{
864}
865DEFINE_CCW_MACHINE(8_2, "8.2", true);
866
Cornelia Huckf9be4772023-03-14 18:30:09 +0100867static void ccw_machine_8_1_instance_options(MachineState *machine)
868{
Cornelia Huck95f5c892023-07-18 16:22:35 +0200869 ccw_machine_8_2_instance_options(machine);
Cornelia Huckf9be4772023-03-14 18:30:09 +0100870}
871
872static void ccw_machine_8_1_class_options(MachineClass *mc)
873{
Cornelia Huck95f5c892023-07-18 16:22:35 +0200874 ccw_machine_8_2_class_options(mc);
875 compat_props_add(mc->compat_props, hw_compat_8_1, hw_compat_8_1_len);
Pierre Morel5de1aff2023-10-16 20:39:06 +0200876 mc->smp_props.drawers_supported = false;
877 mc->smp_props.books_supported = false;
Cornelia Huckf9be4772023-03-14 18:30:09 +0100878}
Cornelia Huck95f5c892023-07-18 16:22:35 +0200879DEFINE_CCW_MACHINE(8_1, "8.1", false);
Cornelia Huckf9be4772023-03-14 18:30:09 +0100880
Cornelia Huckdb723c82022-12-12 16:21:44 +0100881static void ccw_machine_8_0_instance_options(MachineState *machine)
882{
Cornelia Huckf9be4772023-03-14 18:30:09 +0100883 ccw_machine_8_1_instance_options(machine);
Cornelia Huckdb723c82022-12-12 16:21:44 +0100884}
885
886static void ccw_machine_8_0_class_options(MachineClass *mc)
887{
Cornelia Huckf9be4772023-03-14 18:30:09 +0100888 ccw_machine_8_1_class_options(mc);
889 compat_props_add(mc->compat_props, hw_compat_8_0, hw_compat_8_0_len);
Cornelia Huckdb723c82022-12-12 16:21:44 +0100890}
Cornelia Huckf9be4772023-03-14 18:30:09 +0100891DEFINE_CCW_MACHINE(8_0, "8.0", false);
Cornelia Huckdb723c82022-12-12 16:21:44 +0100892
Cornelia Huckf514e142022-07-27 14:17:55 +0200893static void ccw_machine_7_2_instance_options(MachineState *machine)
894{
Cornelia Huckdb723c82022-12-12 16:21:44 +0100895 ccw_machine_8_0_instance_options(machine);
Cornelia Huckf514e142022-07-27 14:17:55 +0200896}
897
898static void ccw_machine_7_2_class_options(MachineClass *mc)
899{
Cornelia Huckdb723c82022-12-12 16:21:44 +0100900 ccw_machine_8_0_class_options(mc);
901 compat_props_add(mc->compat_props, hw_compat_7_2, hw_compat_7_2_len);
Cornelia Huckf514e142022-07-27 14:17:55 +0200902}
Cornelia Huckdb723c82022-12-12 16:21:44 +0100903DEFINE_CCW_MACHINE(7_2, "7.2", false);
Cornelia Huckf514e142022-07-27 14:17:55 +0200904
Cornelia Huck0ca70362022-03-16 15:55:21 +0100905static void ccw_machine_7_1_instance_options(MachineState *machine)
906{
Jason A. Donenfeld9f17bfd2022-09-22 17:38:20 +0200907 static const S390FeatInit qemu_cpu_feat = { S390_FEAT_LIST_QEMU_V7_1 };
908
Cornelia Huckf514e142022-07-27 14:17:55 +0200909 ccw_machine_7_2_instance_options(machine);
Christian Borntraeger1d41de52022-07-27 13:51:20 +0000910 s390_cpudef_featoff_greater(16, 1, S390_FEAT_PAIE);
Jason A. Donenfeld9f17bfd2022-09-22 17:38:20 +0200911 s390_set_qemu_cpu_model(0x8561, 15, 1, qemu_cpu_feat);
Cornelia Huck0ca70362022-03-16 15:55:21 +0100912}
913
914static void ccw_machine_7_1_class_options(MachineClass *mc)
915{
Pierre Morel6393b292022-11-03 18:01:41 +0100916 S390CcwMachineClass *s390mc = S390_CCW_MACHINE_CLASS(mc);
Cédric Le Goaterd3d1a402022-11-07 17:13:49 +0100917 static GlobalProperty compat[] = {
918 { TYPE_S390_PCI_DEVICE, "interpret", "off", },
919 { TYPE_S390_PCI_DEVICE, "forwarding-assist", "off", },
920 };
Pierre Morel6393b292022-11-03 18:01:41 +0100921
Cornelia Huckf514e142022-07-27 14:17:55 +0200922 ccw_machine_7_2_class_options(mc);
923 compat_props_add(mc->compat_props, hw_compat_7_1, hw_compat_7_1_len);
Cédric Le Goaterd3d1a402022-11-07 17:13:49 +0100924 compat_props_add(mc->compat_props, compat, G_N_ELEMENTS(compat));
Pierre Morel6393b292022-11-03 18:01:41 +0100925 s390mc->max_threads = S390_MAX_CPUS;
Cornelia Huck0ca70362022-03-16 15:55:21 +0100926}
Cornelia Huckf514e142022-07-27 14:17:55 +0200927DEFINE_CCW_MACHINE(7_1, "7.1", false);
Cornelia Huck0ca70362022-03-16 15:55:21 +0100928
Cornelia Huck01854af2021-12-17 15:39:48 +0100929static void ccw_machine_7_0_instance_options(MachineState *machine)
930{
David Miller4f9b6c72022-04-28 11:47:07 +0200931 static const S390FeatInit qemu_cpu_feat = { S390_FEAT_LIST_QEMU_V7_0 };
932
Cornelia Huck0ca70362022-03-16 15:55:21 +0100933 ccw_machine_7_1_instance_options(machine);
David Miller4f9b6c72022-04-28 11:47:07 +0200934 s390_set_qemu_cpu_model(0x8561, 15, 1, qemu_cpu_feat);
Cornelia Huck01854af2021-12-17 15:39:48 +0100935}
936
937static void ccw_machine_7_0_class_options(MachineClass *mc)
938{
Cornelia Huck0ca70362022-03-16 15:55:21 +0100939 ccw_machine_7_1_class_options(mc);
940 compat_props_add(mc->compat_props, hw_compat_7_0, hw_compat_7_0_len);
Cornelia Huck01854af2021-12-17 15:39:48 +0100941}
Cornelia Huck0ca70362022-03-16 15:55:21 +0100942DEFINE_CCW_MACHINE(7_0, "7.0", false);
Cornelia Huck01854af2021-12-17 15:39:48 +0100943
Yanan Wang52e64f52021-08-31 09:54:26 +0800944static void ccw_machine_6_2_instance_options(MachineState *machine)
945{
David Miller8a4eafb2022-02-23 17:31:15 -0500946 static const S390FeatInit qemu_cpu_feat = { S390_FEAT_LIST_QEMU_V6_2 };
947
Cornelia Huck01854af2021-12-17 15:39:48 +0100948 ccw_machine_7_0_instance_options(machine);
David Miller8a4eafb2022-02-23 17:31:15 -0500949 s390_set_qemu_cpu_model(0x3906, 14, 2, qemu_cpu_feat);
Yanan Wang52e64f52021-08-31 09:54:26 +0800950}
951
952static void ccw_machine_6_2_class_options(MachineClass *mc)
953{
Cornelia Huck01854af2021-12-17 15:39:48 +0100954 ccw_machine_7_0_class_options(mc);
955 compat_props_add(mc->compat_props, hw_compat_6_2, hw_compat_6_2_len);
Yanan Wang52e64f52021-08-31 09:54:26 +0800956}
Cornelia Huck01854af2021-12-17 15:39:48 +0100957DEFINE_CCW_MACHINE(6_2, "6.2", false);
Yanan Wang52e64f52021-08-31 09:54:26 +0800958
Cornelia Huckda7e13c2021-03-31 13:19:00 +0200959static void ccw_machine_6_1_instance_options(MachineState *machine)
960{
Yanan Wang52e64f52021-08-31 09:54:26 +0800961 ccw_machine_6_2_instance_options(machine);
Christian Borntraeger30e398f2021-09-07 10:10:17 +0000962 s390_cpudef_featoff_greater(16, 1, S390_FEAT_NNPA);
963 s390_cpudef_featoff_greater(16, 1, S390_FEAT_VECTOR_PACKED_DECIMAL_ENH2);
964 s390_cpudef_featoff_greater(16, 1, S390_FEAT_BEAR_ENH);
965 s390_cpudef_featoff_greater(16, 1, S390_FEAT_RDP);
966 s390_cpudef_featoff_greater(16, 1, S390_FEAT_PAI);
Cornelia Huckda7e13c2021-03-31 13:19:00 +0200967}
968
969static void ccw_machine_6_1_class_options(MachineClass *mc)
970{
Yanan Wang52e64f52021-08-31 09:54:26 +0800971 ccw_machine_6_2_class_options(mc);
972 compat_props_add(mc->compat_props, hw_compat_6_1, hw_compat_6_1_len);
Yanan Wang2b526192021-09-29 10:58:14 +0800973 mc->smp_props.prefer_sockets = true;
Cornelia Huckda7e13c2021-03-31 13:19:00 +0200974}
Yanan Wang52e64f52021-08-31 09:54:26 +0800975DEFINE_CCW_MACHINE(6_1, "6.1", false);
Cornelia Huckda7e13c2021-03-31 13:19:00 +0200976
Cornelia Huck576a00b2020-11-09 18:39:28 +0100977static void ccw_machine_6_0_instance_options(MachineState *machine)
978{
David Hildenbrand463e50d2021-06-08 11:23:37 +0200979 static const S390FeatInit qemu_cpu_feat = { S390_FEAT_LIST_QEMU_V6_0 };
980
Cornelia Huckda7e13c2021-03-31 13:19:00 +0200981 ccw_machine_6_1_instance_options(machine);
David Hildenbrand463e50d2021-06-08 11:23:37 +0200982 s390_set_qemu_cpu_model(0x2964, 13, 2, qemu_cpu_feat);
Cornelia Huck576a00b2020-11-09 18:39:28 +0100983}
984
985static void ccw_machine_6_0_class_options(MachineClass *mc)
986{
Cornelia Huckda7e13c2021-03-31 13:19:00 +0200987 ccw_machine_6_1_class_options(mc);
988 compat_props_add(mc->compat_props, hw_compat_6_0, hw_compat_6_0_len);
Cornelia Huck576a00b2020-11-09 18:39:28 +0100989}
Cornelia Huckda7e13c2021-03-31 13:19:00 +0200990DEFINE_CCW_MACHINE(6_0, "6.0", false);
Cornelia Huck576a00b2020-11-09 18:39:28 +0100991
Cornelia Huck3ff3c5d2020-08-19 16:40:16 +0200992static void ccw_machine_5_2_instance_options(MachineState *machine)
993{
Cornelia Huck576a00b2020-11-09 18:39:28 +0100994 ccw_machine_6_0_instance_options(machine);
Cornelia Huck3ff3c5d2020-08-19 16:40:16 +0200995}
996
997static void ccw_machine_5_2_class_options(MachineClass *mc)
998{
Cornelia Huck576a00b2020-11-09 18:39:28 +0100999 ccw_machine_6_0_class_options(mc);
1000 compat_props_add(mc->compat_props, hw_compat_5_2, hw_compat_5_2_len);
Cornelia Huck3ff3c5d2020-08-19 16:40:16 +02001001}
Cornelia Huck576a00b2020-11-09 18:39:28 +01001002DEFINE_CCW_MACHINE(5_2, "5.2", false);
Cornelia Huck3ff3c5d2020-08-19 16:40:16 +02001003
Cornelia Huck541aaa12020-04-29 16:46:05 +02001004static void ccw_machine_5_1_instance_options(MachineState *machine)
1005{
Cornelia Huck3ff3c5d2020-08-19 16:40:16 +02001006 ccw_machine_5_2_instance_options(machine);
Cornelia Huck541aaa12020-04-29 16:46:05 +02001007}
1008
1009static void ccw_machine_5_1_class_options(MachineClass *mc)
1010{
Cornelia Huck3ff3c5d2020-08-19 16:40:16 +02001011 ccw_machine_5_2_class_options(mc);
1012 compat_props_add(mc->compat_props, hw_compat_5_1, hw_compat_5_1_len);
Cornelia Huck541aaa12020-04-29 16:46:05 +02001013}
Cornelia Huck3ff3c5d2020-08-19 16:40:16 +02001014DEFINE_CCW_MACHINE(5_1, "5.1", false);
Cornelia Huck541aaa12020-04-29 16:46:05 +02001015
Cornelia Huck3eb74d22019-11-12 11:48:11 +01001016static void ccw_machine_5_0_instance_options(MachineState *machine)
1017{
Cornelia Huck541aaa12020-04-29 16:46:05 +02001018 ccw_machine_5_1_instance_options(machine);
Cornelia Huck3eb74d22019-11-12 11:48:11 +01001019}
1020
1021static void ccw_machine_5_0_class_options(MachineClass *mc)
1022{
Cornelia Huck541aaa12020-04-29 16:46:05 +02001023 ccw_machine_5_1_class_options(mc);
1024 compat_props_add(mc->compat_props, hw_compat_5_0, hw_compat_5_0_len);
Cornelia Huck3eb74d22019-11-12 11:48:11 +01001025}
Cornelia Huck541aaa12020-04-29 16:46:05 +02001026DEFINE_CCW_MACHINE(5_0, "5.0", false);
Cornelia Huck3eb74d22019-11-12 11:48:11 +01001027
Cornelia Huck9aec2e52019-07-24 12:35:24 +02001028static void ccw_machine_4_2_instance_options(MachineState *machine)
1029{
Cornelia Huck3eb74d22019-11-12 11:48:11 +01001030 ccw_machine_5_0_instance_options(machine);
Cornelia Huck9aec2e52019-07-24 12:35:24 +02001031}
1032
1033static void ccw_machine_4_2_class_options(MachineClass *mc)
1034{
Cornelia Huck3eb74d22019-11-12 11:48:11 +01001035 ccw_machine_5_0_class_options(mc);
Christian Borntraeger5c30ef92020-04-01 08:37:54 -04001036 mc->fixup_ram_size = s390_fixup_ram_size;
Evgeny Yakovlev5f258572019-11-05 21:22:17 +03001037 compat_props_add(mc->compat_props, hw_compat_4_2, hw_compat_4_2_len);
Cornelia Huck9aec2e52019-07-24 12:35:24 +02001038}
Cornelia Huck3eb74d22019-11-12 11:48:11 +01001039DEFINE_CCW_MACHINE(4_2, "4.2", false);
Cornelia Huck9aec2e52019-07-24 12:35:24 +02001040
Cornelia Huck9bf26502019-04-11 12:20:25 +02001041static void ccw_machine_4_1_instance_options(MachineState *machine)
1042{
David Hildenbrandfaa40172019-08-05 10:13:52 +02001043 static const S390FeatInit qemu_cpu_feat = { S390_FEAT_LIST_QEMU_V4_1 };
Cornelia Huck9aec2e52019-07-24 12:35:24 +02001044 ccw_machine_4_2_instance_options(machine);
David Hildenbrandfaa40172019-08-05 10:13:52 +02001045 s390_set_qemu_cpu_model(0x2964, 13, 2, qemu_cpu_feat);
Cornelia Huck9bf26502019-04-11 12:20:25 +02001046}
1047
1048static void ccw_machine_4_1_class_options(MachineClass *mc)
1049{
Cornelia Huck9aec2e52019-07-24 12:35:24 +02001050 ccw_machine_4_2_class_options(mc);
1051 compat_props_add(mc->compat_props, hw_compat_4_1, hw_compat_4_1_len);
Cornelia Huck9bf26502019-04-11 12:20:25 +02001052}
Cornelia Huck9aec2e52019-07-24 12:35:24 +02001053DEFINE_CCW_MACHINE(4_1, "4.1", false);
Cornelia Huck9bf26502019-04-11 12:20:25 +02001054
Cornelia Huck8c7b0c72018-11-19 11:58:53 +01001055static void ccw_machine_4_0_instance_options(MachineState *machine)
1056{
David Hildenbrand08ef92d2019-02-27 09:12:09 +01001057 static const S390FeatInit qemu_cpu_feat = { S390_FEAT_LIST_QEMU_V4_0 };
Cornelia Huck9bf26502019-04-11 12:20:25 +02001058 ccw_machine_4_1_instance_options(machine);
David Hildenbrand08ef92d2019-02-27 09:12:09 +01001059 s390_set_qemu_cpu_model(0x2827, 12, 2, qemu_cpu_feat);
Cornelia Huck8c7b0c72018-11-19 11:58:53 +01001060}
1061
1062static void ccw_machine_4_0_class_options(MachineClass *mc)
1063{
Cornelia Huck9bf26502019-04-11 12:20:25 +02001064 ccw_machine_4_1_class_options(mc);
1065 compat_props_add(mc->compat_props, hw_compat_4_0, hw_compat_4_0_len);
Cornelia Huck8c7b0c72018-11-19 11:58:53 +01001066}
Cornelia Huck9bf26502019-04-11 12:20:25 +02001067DEFINE_CCW_MACHINE(4_0, "4.0", false);
Cornelia Huck8c7b0c72018-11-19 11:58:53 +01001068
Cornelia Huck9ca056d2018-07-23 15:00:54 +02001069static void ccw_machine_3_1_instance_options(MachineState *machine)
1070{
David Hildenbrandd646b162019-02-12 12:23:23 +01001071 static const S390FeatInit qemu_cpu_feat = { S390_FEAT_LIST_QEMU_V3_1 };
Cornelia Huck8c7b0c72018-11-19 11:58:53 +01001072 ccw_machine_4_0_instance_options(machine);
Collin Walling84176c72019-02-11 20:16:56 -05001073 s390_cpudef_featoff_greater(14, 1, S390_FEAT_MULTIPLE_EPOCH);
1074 s390_cpudef_group_featoff_greater(14, 1, S390_FEAT_GROUP_MULTIPLE_EPOCH_PTFF);
David Hildenbrandd646b162019-02-12 12:23:23 +01001075 s390_set_qemu_cpu_model(0x2827, 12, 2, qemu_cpu_feat);
Cornelia Huck9ca056d2018-07-23 15:00:54 +02001076}
1077
1078static void ccw_machine_3_1_class_options(MachineClass *mc)
1079{
Cornelia Huck8c7b0c72018-11-19 11:58:53 +01001080 ccw_machine_4_0_class_options(mc);
Marc-André Lureauabd93cc2018-12-12 19:36:30 +04001081 compat_props_add(mc->compat_props, hw_compat_3_1, hw_compat_3_1_len);
Cornelia Huck9ca056d2018-07-23 15:00:54 +02001082}
Cornelia Huck8c7b0c72018-11-19 11:58:53 +01001083DEFINE_CCW_MACHINE(3_1, "3.1", false);
Cornelia Huck9ca056d2018-07-23 15:00:54 +02001084
Peter Maydell2c5a2ee2018-05-22 11:39:58 +01001085static void ccw_machine_3_0_instance_options(MachineState *machine)
Cornelia Huck7a9cb3a2018-03-29 13:22:56 +02001086{
Cornelia Huck9ca056d2018-07-23 15:00:54 +02001087 ccw_machine_3_1_instance_options(machine);
Cornelia Huck7a9cb3a2018-03-29 13:22:56 +02001088}
1089
Peter Maydell2c5a2ee2018-05-22 11:39:58 +01001090static void ccw_machine_3_0_class_options(MachineClass *mc)
Cornelia Huck7a9cb3a2018-03-29 13:22:56 +02001091{
Eduardo Habkostb1af5872020-08-25 15:20:44 -04001092 S390CcwMachineClass *s390mc = S390_CCW_MACHINE_CLASS(mc);
Janosch Frank28221f92018-09-28 11:34:35 +02001093
1094 s390mc->hpage_1m_allowed = false;
Cornelia Huck9ca056d2018-07-23 15:00:54 +02001095 ccw_machine_3_1_class_options(mc);
Marc-André Lureauddb32352018-12-12 19:36:30 +04001096 compat_props_add(mc->compat_props, hw_compat_3_0, hw_compat_3_0_len);
Cornelia Huck7a9cb3a2018-03-29 13:22:56 +02001097}
Cornelia Huck9ca056d2018-07-23 15:00:54 +02001098DEFINE_CCW_MACHINE(3_0, "3.0", false);
Cornelia Huck7a9cb3a2018-03-29 13:22:56 +02001099
Cornelia Huck67ee0ce2017-11-24 16:26:51 +01001100static void ccw_machine_2_12_instance_options(MachineState *machine)
1101{
Peter Maydell2c5a2ee2018-05-22 11:39:58 +01001102 ccw_machine_3_0_instance_options(machine);
Christian Borntraeger87273152018-06-26 14:38:30 +02001103 s390_cpudef_featoff_greater(11, 1, S390_FEAT_PPA15);
1104 s390_cpudef_featoff_greater(11, 1, S390_FEAT_BPB);
Cornelia Huck67ee0ce2017-11-24 16:26:51 +01001105}
1106
1107static void ccw_machine_2_12_class_options(MachineClass *mc)
1108{
Peter Maydell2c5a2ee2018-05-22 11:39:58 +01001109 ccw_machine_3_0_class_options(mc);
Marc-André Lureau0d473102018-12-12 19:36:30 +04001110 compat_props_add(mc->compat_props, hw_compat_2_12, hw_compat_2_12_len);
Cornelia Huck67ee0ce2017-11-24 16:26:51 +01001111}
Cornelia Huck7a9cb3a2018-03-29 13:22:56 +02001112DEFINE_CCW_MACHINE(2_12, "2.12", false);
Cornelia Huck67ee0ce2017-11-24 16:26:51 +01001113
Cornelia Huck70d8d9a2017-08-10 14:07:31 +02001114static void ccw_machine_2_11_instance_options(MachineState *machine)
1115{
David Hildenbrand35b4df62017-12-08 17:55:29 +01001116 static const S390FeatInit qemu_cpu_feat = { S390_FEAT_LIST_QEMU_V2_11 };
Cornelia Huck67ee0ce2017-11-24 16:26:51 +01001117 ccw_machine_2_12_instance_options(machine);
David Hildenbrand35b4df62017-12-08 17:55:29 +01001118
1119 /* before 2.12 we emulated the very first z900 */
1120 s390_set_qemu_cpu_model(0x2064, 7, 1, qemu_cpu_feat);
Cornelia Huck70d8d9a2017-08-10 14:07:31 +02001121}
1122
1123static void ccw_machine_2_11_class_options(MachineClass *mc)
1124{
Marc-André Lureau88cbe072018-12-12 18:01:23 +04001125 static GlobalProperty compat[] = {
Eduardo Habkost6c36bdd2019-01-07 17:30:20 -02001126 { TYPE_SCLP_EVENT_FACILITY, "allow_all_mask_sizes", "off", },
Marc-André Lureau88cbe072018-12-12 18:01:23 +04001127 };
1128
Cornelia Huck67ee0ce2017-11-24 16:26:51 +01001129 ccw_machine_2_12_class_options(mc);
Marc-André Lureau43df70a2018-12-12 19:36:30 +04001130 compat_props_add(mc->compat_props, hw_compat_2_11, hw_compat_2_11_len);
Marc-André Lureau88cbe072018-12-12 18:01:23 +04001131 compat_props_add(mc->compat_props, compat, G_N_ELEMENTS(compat));
Cornelia Huck70d8d9a2017-08-10 14:07:31 +02001132}
Cornelia Huck67ee0ce2017-11-24 16:26:51 +01001133DEFINE_CCW_MACHINE(2_11, "2.11", false);
Cornelia Huck70d8d9a2017-08-10 14:07:31 +02001134
Cornelia Huck10890872017-04-03 17:41:33 +02001135static void ccw_machine_2_10_instance_options(MachineState *machine)
1136{
Cornelia Huck70d8d9a2017-08-10 14:07:31 +02001137 ccw_machine_2_11_instance_options(machine);
Cornelia Huck10890872017-04-03 17:41:33 +02001138}
1139
1140static void ccw_machine_2_10_class_options(MachineClass *mc)
1141{
Cornelia Huck70d8d9a2017-08-10 14:07:31 +02001142 ccw_machine_2_11_class_options(mc);
Marc-André Lureau503224f2018-12-12 19:36:30 +04001143 compat_props_add(mc->compat_props, hw_compat_2_10, hw_compat_2_10_len);
Cornelia Huck10890872017-04-03 17:41:33 +02001144}
Cornelia Huck70d8d9a2017-08-10 14:07:31 +02001145DEFINE_CCW_MACHINE(2_10, "2.10", false);
Cornelia Huck10890872017-04-03 17:41:33 +02001146
Cornelia Huck113725a2016-11-30 15:52:46 +01001147static void ccw_machine_2_9_instance_options(MachineState *machine)
1148{
Cornelia Huck10890872017-04-03 17:41:33 +02001149 ccw_machine_2_10_instance_options(machine);
Jason J. Herne7223bcc2017-04-10 09:39:00 -04001150 s390_cpudef_featoff_greater(12, 1, S390_FEAT_ESOP);
1151 s390_cpudef_featoff_greater(12, 1, S390_FEAT_SIDE_EFFECT_ACCESS_ESOP2);
Yi Min Zhao3b00f702017-06-14 13:25:58 +08001152 s390_cpudef_featoff_greater(12, 1, S390_FEAT_ZPCI);
1153 s390_cpudef_featoff_greater(12, 1, S390_FEAT_ADAPTER_INT_SUPPRESSION);
1154 s390_cpudef_featoff_greater(12, 1, S390_FEAT_ADAPTER_EVENT_NOTIFICATION);
Cornelia Huck113725a2016-11-30 15:52:46 +01001155}
1156
1157static void ccw_machine_2_9_class_options(MachineClass *mc)
1158{
Eduardo Habkostb1af5872020-08-25 15:20:44 -04001159 S390CcwMachineClass *s390mc = S390_CCW_MACHINE_CLASS(mc);
Marc-André Lureau88cbe072018-12-12 18:01:23 +04001160 static GlobalProperty compat[] = {
Eduardo Habkost6c36bdd2019-01-07 17:30:20 -02001161 { TYPE_S390_STATTRIB, "migration-enabled", "off", },
Marc-André Lureau88cbe072018-12-12 18:01:23 +04001162 };
Halil Pasic52629b32017-07-11 16:54:37 +02001163
Cornelia Huck10890872017-04-03 17:41:33 +02001164 ccw_machine_2_10_class_options(mc);
Marc-André Lureau3e803152018-12-12 19:36:30 +04001165 compat_props_add(mc->compat_props, hw_compat_2_9, hw_compat_2_9_len);
Marc-André Lureau88cbe072018-12-12 18:01:23 +04001166 compat_props_add(mc->compat_props, compat, G_N_ELEMENTS(compat));
Halil Pasic52629b32017-07-11 16:54:37 +02001167 s390mc->css_migration_enabled = false;
Cornelia Huck113725a2016-11-30 15:52:46 +01001168}
Cornelia Huck10890872017-04-03 17:41:33 +02001169DEFINE_CCW_MACHINE(2_9, "2.9", false);
Cornelia Huck113725a2016-11-30 15:52:46 +01001170
Cornelia Huck61823982016-08-12 09:26:52 +02001171static void ccw_machine_2_8_instance_options(MachineState *machine)
1172{
Cornelia Huck113725a2016-11-30 15:52:46 +01001173 ccw_machine_2_9_instance_options(machine);
Cornelia Huck61823982016-08-12 09:26:52 +02001174}
1175
1176static void ccw_machine_2_8_class_options(MachineClass *mc)
1177{
Marc-André Lureau88cbe072018-12-12 18:01:23 +04001178 static GlobalProperty compat[] = {
Eduardo Habkost6c36bdd2019-01-07 17:30:20 -02001179 { TYPE_S390_FLIC_COMMON, "adapter_routes_max_batch", "64", },
Marc-André Lureau88cbe072018-12-12 18:01:23 +04001180 };
1181
Cornelia Huck113725a2016-11-30 15:52:46 +01001182 ccw_machine_2_9_class_options(mc);
Marc-André Lureauedc24cc2018-12-12 19:36:30 +04001183 compat_props_add(mc->compat_props, hw_compat_2_8, hw_compat_2_8_len);
Marc-André Lureau88cbe072018-12-12 18:01:23 +04001184 compat_props_add(mc->compat_props, compat, G_N_ELEMENTS(compat));
Cornelia Huck61823982016-08-12 09:26:52 +02001185}
Cornelia Huck113725a2016-11-30 15:52:46 +01001186DEFINE_CCW_MACHINE(2_8, "2.8", false);
Cornelia Huck61823982016-08-12 09:26:52 +02001187
Cornelia Huck946e55f2016-04-25 10:37:23 +02001188static void ccw_machine_2_7_instance_options(MachineState *machine)
1189{
Cornelia Huck61823982016-08-12 09:26:52 +02001190 ccw_machine_2_8_instance_options(machine);
Cornelia Huck946e55f2016-04-25 10:37:23 +02001191}
1192
1193static void ccw_machine_2_7_class_options(MachineClass *mc)
1194{
Eduardo Habkostb1af5872020-08-25 15:20:44 -04001195 S390CcwMachineClass *s390mc = S390_CCW_MACHINE_CLASS(mc);
Christian Borntraegere73316d2016-09-07 12:50:40 +02001196
1197 s390mc->cpu_model_allowed = false;
Cornelia Huck61823982016-08-12 09:26:52 +02001198 ccw_machine_2_8_class_options(mc);
Marc-André Lureau5a995062018-12-12 19:36:30 +04001199 compat_props_add(mc->compat_props, hw_compat_2_7, hw_compat_2_7_len);
Cornelia Huck946e55f2016-04-25 10:37:23 +02001200}
Cornelia Huck61823982016-08-12 09:26:52 +02001201DEFINE_CCW_MACHINE(2_7, "2.7", false);
Cornelia Huck946e55f2016-04-25 10:37:23 +02001202
Janosch Frank4fca6542016-03-03 12:48:34 +01001203static void ccw_machine_2_6_instance_options(MachineState *machine)
Christian Borntraegerc4d3c0a2015-07-01 11:16:57 +02001204{
Cornelia Huck946e55f2016-04-25 10:37:23 +02001205 ccw_machine_2_7_instance_options(machine);
Christian Borntraegerc4d3c0a2015-07-01 11:16:57 +02001206}
1207
Janosch Frank4fca6542016-03-03 12:48:34 +01001208static void ccw_machine_2_6_class_options(MachineClass *mc)
Cornelia Huck84b48ad2015-07-17 13:16:52 +02001209{
Eduardo Habkostb1af5872020-08-25 15:20:44 -04001210 S390CcwMachineClass *s390mc = S390_CCW_MACHINE_CLASS(mc);
Marc-André Lureau88cbe072018-12-12 18:01:23 +04001211 static GlobalProperty compat[] = {
Eduardo Habkost6c36bdd2019-01-07 17:30:20 -02001212 { TYPE_S390_IPL, "iplbext_migration", "off", },
1213 { TYPE_VIRTUAL_CSS_BRIDGE, "css_dev_path", "off", },
Marc-André Lureau88cbe072018-12-12 18:01:23 +04001214 };
Fan Zhang97002302016-03-09 13:11:17 +01001215
1216 s390mc->ri_allowed = false;
Cornelia Huck946e55f2016-04-25 10:37:23 +02001217 ccw_machine_2_7_class_options(mc);
Marc-André Lureauff8f2612018-12-12 19:36:30 +04001218 compat_props_add(mc->compat_props, hw_compat_2_6, hw_compat_2_6_len);
Marc-André Lureau88cbe072018-12-12 18:01:23 +04001219 compat_props_add(mc->compat_props, compat, G_N_ELEMENTS(compat));
Janosch Frank4fca6542016-03-03 12:48:34 +01001220}
Cornelia Huck946e55f2016-04-25 10:37:23 +02001221DEFINE_CCW_MACHINE(2_6, "2.6", false);
Cornelia Huck84b48ad2015-07-17 13:16:52 +02001222
Janosch Frank4fca6542016-03-03 12:48:34 +01001223static void ccw_machine_2_5_instance_options(MachineState *machine)
1224{
Cornelia Huck946e55f2016-04-25 10:37:23 +02001225 ccw_machine_2_6_instance_options(machine);
Cornelia Huck84b48ad2015-07-17 13:16:52 +02001226}
1227
Janosch Frank4fca6542016-03-03 12:48:34 +01001228static void ccw_machine_2_5_class_options(MachineClass *mc)
Cornelia Huckb21b7592015-11-30 10:45:41 +01001229{
Cornelia Huck946e55f2016-04-25 10:37:23 +02001230 ccw_machine_2_6_class_options(mc);
Marc-André Lureaufe759612018-12-12 19:36:30 +04001231 compat_props_add(mc->compat_props, hw_compat_2_5, hw_compat_2_5_len);
Janosch Frank4fca6542016-03-03 12:48:34 +01001232}
1233DEFINE_CCW_MACHINE(2_5, "2.5", false);
Cornelia Huckb21b7592015-11-30 10:45:41 +01001234
Janosch Frank4fca6542016-03-03 12:48:34 +01001235static void ccw_machine_2_4_instance_options(MachineState *machine)
1236{
1237 ccw_machine_2_5_instance_options(machine);
Cornelia Huckb21b7592015-11-30 10:45:41 +01001238}
1239
Janosch Frank4fca6542016-03-03 12:48:34 +01001240static void ccw_machine_2_4_class_options(MachineClass *mc)
1241{
Marc-André Lureau88cbe072018-12-12 18:01:23 +04001242 static GlobalProperty compat[] = {
Eduardo Habkost6c36bdd2019-01-07 17:30:20 -02001243 { TYPE_S390_SKEYS, "migration-enabled", "off", },
1244 { "virtio-blk-ccw", "max_revision", "0", },
1245 { "virtio-balloon-ccw", "max_revision", "0", },
1246 { "virtio-serial-ccw", "max_revision", "0", },
1247 { "virtio-9p-ccw", "max_revision", "0", },
1248 { "virtio-rng-ccw", "max_revision", "0", },
1249 { "virtio-net-ccw", "max_revision", "0", },
1250 { "virtio-scsi-ccw", "max_revision", "0", },
1251 { "vhost-scsi-ccw", "max_revision", "0", },
Marc-André Lureau88cbe072018-12-12 18:01:23 +04001252 };
1253
Cornelia Huck946e55f2016-04-25 10:37:23 +02001254 ccw_machine_2_5_class_options(mc);
Marc-André Lureau2f99b9c2018-12-12 19:36:30 +04001255 compat_props_add(mc->compat_props, hw_compat_2_4, hw_compat_2_4_len);
Marc-André Lureau88cbe072018-12-12 18:01:23 +04001256 compat_props_add(mc->compat_props, compat, G_N_ELEMENTS(compat));
Janosch Frank4fca6542016-03-03 12:48:34 +01001257}
1258DEFINE_CCW_MACHINE(2_4, "2.4", false);
Cornelia Huckb21b7592015-11-30 10:45:41 +01001259
Alexey Kardashevskiyd07aa7c2014-08-20 22:16:34 +10001260static void ccw_machine_register_types(void)
1261{
1262 type_register_static(&ccw_machine_info);
1263}
1264
1265type_init(ccw_machine_register_types)