2013-01-24 10:08:56 +04:00
|
|
|
/*
|
|
|
|
* virtio ccw machine
|
|
|
|
*
|
2020-03-23 11:36:06 +03:00
|
|
|
* Copyright 2012, 2020 IBM Corp.
|
2017-09-13 16:23:58 +03:00
|
|
|
* Copyright (c) 2009 Alexander Graf <agraf@suse.de>
|
2013-01-24 10:08:56 +04:00
|
|
|
* Author(s): Cornelia Huck <cornelia.huck@de.ibm.com>
|
2020-03-23 11:36:06 +03:00
|
|
|
* Janosch Frank <frankja@linux.ibm.com>
|
2013-01-24 10:08:56 +04:00
|
|
|
*
|
|
|
|
* This work is licensed under the terms of the GNU GPL, version 2 or (at
|
|
|
|
* your option) any later version. See the COPYING file in the top-level
|
|
|
|
* directory.
|
|
|
|
*/
|
|
|
|
|
2016-01-26 21:17:00 +03:00
|
|
|
#include "qemu/osdep.h"
|
include/qemu/osdep.h: Don't include qapi/error.h
Commit 57cb38b included qapi/error.h into qemu/osdep.h to get the
Error typedef. Since then, we've moved to include qemu/osdep.h
everywhere. Its file comment explains: "To avoid getting into
possible circular include dependencies, this file should not include
any other QEMU headers, with the exceptions of config-host.h,
compiler.h, os-posix.h and os-win32.h, all of which are doing a
similar job to this file and are under similar constraints."
qapi/error.h doesn't do a similar job, and it doesn't adhere to
similar constraints: it includes qapi-types.h. That's in excess of
100KiB of crap most .c files don't actually need.
Add the typedef to qemu/typedefs.h, and include that instead of
qapi/error.h. Include qapi/error.h in .c files that need it and don't
get it now. Include qapi-types.h in qom/object.h for uint16List.
Update scripts/clean-includes accordingly. Update it further to match
reality: replace config.h by config-target.h, add sysemu/os-posix.h,
sysemu/os-win32.h. Update the list of includes in the qemu/osdep.h
comment quoted above similarly.
This reduces the number of objects depending on qapi/error.h from "all
of them" to less than a third. Unfortunately, the number depending on
qapi-types.h shrinks only a little. More work is needed for that one.
Signed-off-by: Markus Armbruster <armbru@redhat.com>
[Fix compilation without the spice devel packages. - Paolo]
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
2016-03-14 11:01:28 +03:00
|
|
|
#include "qapi/error.h"
|
2019-04-17 14:31:42 +03:00
|
|
|
#include "exec/ram_addr.h"
|
2017-09-13 16:23:59 +03:00
|
|
|
#include "hw/s390x/s390-virtio-hcall.h"
|
2013-02-04 18:40:22 +04:00
|
|
|
#include "hw/s390x/sclp.h"
|
2013-07-16 11:04:04 +04:00
|
|
|
#include "hw/s390x/s390_flic.h"
|
2015-12-04 14:06:26 +03:00
|
|
|
#include "hw/s390x/ioinst.h"
|
|
|
|
#include "hw/s390x/css.h"
|
2013-01-24 10:08:56 +04:00
|
|
|
#include "virtio-ccw.h"
|
2014-08-28 19:25:33 +04:00
|
|
|
#include "qemu/config-file.h"
|
2019-05-23 17:35:06 +03:00
|
|
|
#include "qemu/ctype.h"
|
2017-09-13 16:24:06 +03:00
|
|
|
#include "qemu/error-report.h"
|
2018-02-01 14:18:46 +03:00
|
|
|
#include "qemu/option.h"
|
2020-04-01 15:37:54 +03:00
|
|
|
#include "qemu/qemu-print.h"
|
2022-03-28 14:41:29 +03:00
|
|
|
#include "qemu/units.h"
|
2020-10-26 18:34:31 +03:00
|
|
|
#include "hw/s390x/s390-pci-bus.h"
|
2019-08-12 08:23:38 +03:00
|
|
|
#include "sysemu/reset.h"
|
2015-06-26 21:01:00 +03:00
|
|
|
#include "hw/s390x/storage-keys.h"
|
2016-08-15 19:43:14 +03:00
|
|
|
#include "hw/s390x/storage-attributes.h"
|
s390x/sclp: proper support of larger send and receive masks
Until 67915de9f0383ccf4a ("s390x/event-facility: variable-length event masks")
we only supported sclp event masks with a size of exactly 4 bytes, even
though the architecture allows the guests to set up sclp event masks
from 1 to 1021 bytes in length.
After that patch, the behaviour was almost compliant, but some issues
were still remaining, in particular regarding the handling of selective
reads and migration.
When setting the sclp event mask, a mask size is also specified. Until
now we only considered the size in order to decide which bits to save
in the internal state. On the other hand, when a guest performs a
selective read, it sends a mask, but it does not specify a size; the
implied size is the size of the last mask that has been set.
Specifying bits in the mask of selective read that are not available in
the internal mask should return an error, and bits past the end of the
mask should obviously be ignored. This can only be achieved by keeping
track of the lenght of the mask.
The mask length is thus now part of the internal state that needs to be
migrated.
This patch fixes the handling of selective reads, whose size will now
match the length of the event mask, as per architecture.
While the default behaviour is to be compliant with the architecture,
when using older machine models the old broken behaviour is selected
(allowing only masks of size exactly 4), in order to be able to migrate
toward older versions.
Fixes: 67915de9f0383ccf4a ("s390x/event-facility: variable-length event masks")
Signed-off-by: Claudio Imbrenda <imbrenda@linux.vnet.ibm.com>
Message-Id: <1519407778-23095-2-git-send-email-imbrenda@linux.vnet.ibm.com>
Reviewed-by: Christian Borntraeger <borntraeger@de.ibm.com>
Signed-off-by: Cornelia Huck <cohuck@redhat.com>
2018-02-23 20:42:56 +03:00
|
|
|
#include "hw/s390x/event-facility.h"
|
2015-07-13 15:04:36 +03:00
|
|
|
#include "ipl.h"
|
2016-03-07 11:04:21 +03:00
|
|
|
#include "hw/s390x/s390-virtio-ccw.h"
|
2015-11-06 14:32:40 +03:00
|
|
|
#include "hw/s390x/css-bridge.h"
|
2018-10-10 20:03:06 +03:00
|
|
|
#include "hw/s390x/ap-bridge.h"
|
2017-04-24 14:42:55 +03:00
|
|
|
#include "migration/register.h"
|
2017-04-10 16:39:00 +03:00
|
|
|
#include "cpu_models.h"
|
2017-09-13 16:23:58 +03:00
|
|
|
#include "hw/nmi.h"
|
2019-08-12 08:23:51 +03:00
|
|
|
#include "hw/qdev-properties.h"
|
2018-06-27 16:44:04 +03:00
|
|
|
#include "hw/s390x/tod.h"
|
2019-08-12 08:23:58 +03:00
|
|
|
#include "sysemu/sysemu.h"
|
2023-02-14 19:30:35 +03:00
|
|
|
#include "sysemu/cpus.h"
|
2020-03-23 11:36:06 +03:00
|
|
|
#include "hw/s390x/pv.h"
|
2020-03-19 16:19:09 +03:00
|
|
|
#include "migration/blocker.h"
|
2022-11-03 20:01:40 +03:00
|
|
|
#include "qapi/visitor.h"
|
2020-03-19 16:19:09 +03:00
|
|
|
|
|
|
|
static Error *pv_mig_blocker;
|
2017-09-13 16:23:58 +03:00
|
|
|
|
|
|
|
S390CPU *s390_cpu_addr2state(uint16_t cpu_addr)
|
|
|
|
{
|
2017-09-13 16:24:14 +03:00
|
|
|
static MachineState *ms;
|
|
|
|
|
|
|
|
if (!ms) {
|
|
|
|
ms = MACHINE(qdev_get_machine());
|
|
|
|
g_assert(ms->possible_cpus);
|
2017-09-13 16:23:58 +03:00
|
|
|
}
|
|
|
|
|
2017-09-13 16:24:14 +03:00
|
|
|
/* CPU address corresponds to the core_id and the index */
|
|
|
|
if (cpu_addr >= ms->possible_cpus->len) {
|
|
|
|
return NULL;
|
|
|
|
}
|
|
|
|
return S390_CPU(ms->possible_cpus->cpus[cpu_addr].cpu);
|
2017-09-13 16:23:58 +03:00
|
|
|
}
|
|
|
|
|
2017-10-17 18:13:23 +03:00
|
|
|
static S390CPU *s390x_new_cpu(const char *typename, uint32_t core_id,
|
|
|
|
Error **errp)
|
|
|
|
{
|
|
|
|
S390CPU *cpu = S390_CPU(object_new(typename));
|
2020-07-07 19:05:57 +03:00
|
|
|
S390CPU *ret = NULL;
|
2017-10-17 18:13:23 +03:00
|
|
|
|
2020-07-07 19:06:04 +03:00
|
|
|
if (!object_property_set_int(OBJECT(cpu), "core-id", core_id, errp)) {
|
2017-10-17 18:13:23 +03:00
|
|
|
goto out;
|
|
|
|
}
|
2020-07-07 19:06:04 +03:00
|
|
|
if (!qdev_realize(DEVICE(cpu), NULL, errp)) {
|
2020-07-07 19:05:57 +03:00
|
|
|
goto out;
|
|
|
|
}
|
|
|
|
ret = cpu;
|
2017-10-17 18:13:23 +03:00
|
|
|
|
|
|
|
out:
|
|
|
|
object_unref(OBJECT(cpu));
|
2020-07-07 19:05:57 +03:00
|
|
|
return ret;
|
2017-10-17 18:13:23 +03:00
|
|
|
}
|
|
|
|
|
2017-09-13 16:23:58 +03:00
|
|
|
static void s390_init_cpus(MachineState *machine)
|
|
|
|
{
|
2017-09-13 16:24:13 +03:00
|
|
|
MachineClass *mc = MACHINE_GET_CLASS(machine);
|
2022-11-03 20:01:41 +03:00
|
|
|
S390CcwMachineClass *s390mc = S390_CCW_MACHINE_CLASS(mc);
|
2017-09-13 16:23:58 +03:00
|
|
|
int i;
|
|
|
|
|
2022-11-03 20:01:41 +03:00
|
|
|
if (machine->smp.threads > s390mc->max_threads) {
|
|
|
|
error_report("S390 does not support more than %d threads.",
|
|
|
|
s390mc->max_threads);
|
|
|
|
exit(1);
|
|
|
|
}
|
|
|
|
|
2017-09-13 16:24:13 +03:00
|
|
|
/* initialize possible_cpus */
|
|
|
|
mc->possible_cpu_arch_ids(machine);
|
|
|
|
|
2019-05-18 23:54:24 +03:00
|
|
|
for (i = 0; i < machine->smp.cpus; i++) {
|
2017-09-21 15:59:08 +03:00
|
|
|
s390x_new_cpu(machine->cpu_type, i, &error_fatal);
|
2017-09-13 16:23:58 +03:00
|
|
|
}
|
|
|
|
}
|
2015-03-12 15:53:51 +03:00
|
|
|
|
2015-07-21 11:58:38 +03:00
|
|
|
static const char *const reset_dev_types[] = {
|
2016-07-04 16:46:20 +03:00
|
|
|
TYPE_VIRTUAL_CSS_BRIDGE,
|
2015-07-21 11:58:38 +03:00
|
|
|
"s390-sclp-event-facility",
|
|
|
|
"s390-flic",
|
|
|
|
"diag288",
|
2020-10-15 16:16:07 +03:00
|
|
|
TYPE_S390_PCI_HOST_BRIDGE,
|
2015-07-21 11:58:38 +03:00
|
|
|
};
|
|
|
|
|
2018-04-24 13:18:59 +03:00
|
|
|
static void subsystem_reset(void)
|
2013-07-25 18:37:37 +04:00
|
|
|
{
|
2015-07-21 11:58:38 +03:00
|
|
|
DeviceState *dev;
|
|
|
|
int i;
|
2013-07-25 18:37:37 +04:00
|
|
|
|
2015-07-21 11:58:38 +03:00
|
|
|
for (i = 0; i < ARRAY_SIZE(reset_dev_types); i++) {
|
|
|
|
dev = DEVICE(object_resolve_path_type("", reset_dev_types[i], NULL));
|
|
|
|
if (dev) {
|
2022-12-16 18:55:27 +03:00
|
|
|
device_cold_reset(dev);
|
2015-07-21 11:58:38 +03:00
|
|
|
}
|
2015-06-29 09:21:10 +03:00
|
|
|
}
|
2013-07-25 18:37:37 +04:00
|
|
|
}
|
|
|
|
|
2013-01-24 10:08:56 +04:00
|
|
|
static int virtio_ccw_hcall_notify(const uint64_t *args)
|
|
|
|
{
|
|
|
|
uint64_t subch_id = args[0];
|
|
|
|
uint64_t queue = args[1];
|
|
|
|
SubchDev *sch;
|
|
|
|
int cssid, ssid, schid, m;
|
|
|
|
|
|
|
|
if (ioinst_disassemble_sch_ident(subch_id, &m, &cssid, &ssid, &schid)) {
|
|
|
|
return -EINVAL;
|
|
|
|
}
|
|
|
|
sch = css_find_subch(m, cssid, ssid, schid);
|
|
|
|
if (!sch || !css_subch_visible(sch)) {
|
|
|
|
return -EINVAL;
|
|
|
|
}
|
2015-12-07 18:45:17 +03:00
|
|
|
if (queue >= VIRTIO_QUEUE_MAX) {
|
2013-03-26 20:32:44 +04:00
|
|
|
return -EINVAL;
|
|
|
|
}
|
2013-01-24 10:08:56 +04:00
|
|
|
virtio_queue_notify(virtio_ccw_get_vdev(sch), queue);
|
|
|
|
return 0;
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
static int virtio_ccw_hcall_early_printk(const uint64_t *args)
|
|
|
|
{
|
|
|
|
uint64_t mem = args[0];
|
2020-10-28 13:17:07 +03:00
|
|
|
MachineState *ms = MACHINE(qdev_get_machine());
|
2013-01-24 10:08:56 +04:00
|
|
|
|
2020-10-28 13:17:07 +03:00
|
|
|
if (mem < ms->ram_size) {
|
2013-01-24 10:08:56 +04:00
|
|
|
/* Early printk */
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
return -EINVAL;
|
|
|
|
}
|
|
|
|
|
|
|
|
static void virtio_ccw_register_hcalls(void)
|
|
|
|
{
|
|
|
|
s390_register_virtio_hypercall(KVM_S390_VIRTIO_CCW_NOTIFY,
|
|
|
|
virtio_ccw_hcall_notify);
|
|
|
|
/* Tolerate early printk. */
|
|
|
|
s390_register_virtio_hypercall(KVM_S390_VIRTIO_NOTIFY,
|
|
|
|
virtio_ccw_hcall_early_printk);
|
|
|
|
}
|
|
|
|
|
2020-02-19 19:09:12 +03:00
|
|
|
static void s390_memory_init(MemoryRegion *ram)
|
2013-01-24 10:08:56 +04:00
|
|
|
{
|
|
|
|
MemoryRegion *sysmem = get_system_memory();
|
2015-05-29 16:01:55 +03:00
|
|
|
|
|
|
|
/* allocate RAM for core */
|
2019-09-24 17:47:51 +03:00
|
|
|
memory_region_add_subregion(sysmem, 0, ram);
|
2015-05-29 16:01:55 +03:00
|
|
|
|
2019-04-17 14:31:42 +03:00
|
|
|
/*
|
|
|
|
* Configure the maximum page size. As no memory devices were created
|
|
|
|
* yet, this is the page size of initial memory only.
|
|
|
|
*/
|
2020-07-22 11:40:48 +03:00
|
|
|
s390_set_max_pagesize(qemu_maxrampagesize(), &error_fatal);
|
2015-05-29 16:01:55 +03:00
|
|
|
/* Initialize storage key device */
|
|
|
|
s390_skeys_init();
|
2016-08-15 19:43:14 +03:00
|
|
|
/* Initialize storage attributes device */
|
|
|
|
s390_stattrib_init();
|
2015-05-29 16:01:55 +03:00
|
|
|
}
|
|
|
|
|
2017-09-13 16:23:58 +03:00
|
|
|
static void s390_init_ipl_dev(const char *kernel_filename,
|
|
|
|
const char *kernel_cmdline,
|
|
|
|
const char *initrd_filename, const char *firmware,
|
|
|
|
const char *netboot_fw, bool enforce_bios)
|
|
|
|
{
|
|
|
|
Object *new = object_new(TYPE_S390_IPL);
|
|
|
|
DeviceState *dev = DEVICE(new);
|
2018-03-29 12:10:06 +03:00
|
|
|
char *netboot_fw_prop;
|
2017-09-13 16:23:58 +03:00
|
|
|
|
|
|
|
if (kernel_filename) {
|
|
|
|
qdev_prop_set_string(dev, "kernel", kernel_filename);
|
|
|
|
}
|
|
|
|
if (initrd_filename) {
|
|
|
|
qdev_prop_set_string(dev, "initrd", initrd_filename);
|
|
|
|
}
|
|
|
|
qdev_prop_set_string(dev, "cmdline", kernel_cmdline);
|
|
|
|
qdev_prop_set_string(dev, "firmware", firmware);
|
|
|
|
qdev_prop_set_bit(dev, "enforce_bios", enforce_bios);
|
2018-03-29 12:10:06 +03:00
|
|
|
netboot_fw_prop = object_property_get_str(new, "netboot_fw", &error_abort);
|
|
|
|
if (!strlen(netboot_fw_prop)) {
|
2018-02-27 14:32:34 +03:00
|
|
|
qdev_prop_set_string(dev, "netboot_fw", netboot_fw);
|
|
|
|
}
|
2018-03-29 12:10:06 +03:00
|
|
|
g_free(netboot_fw_prop);
|
2017-09-13 16:23:58 +03:00
|
|
|
object_property_add_child(qdev_get_machine(), TYPE_S390_IPL,
|
qom: Drop parameter @errp of object_property_add() & friends
The only way object_property_add() can fail is when a property with
the same name already exists. Since our property names are all
hardcoded, failure is a programming error, and the appropriate way to
handle it is passing &error_abort.
Same for its variants, except for object_property_add_child(), which
additionally fails when the child already has a parent. Parentage is
also under program control, so this is a programming error, too.
We have a bit over 500 callers. Almost half of them pass
&error_abort, slightly fewer ignore errors, one test case handles
errors, and the remaining few callers pass them to their own callers.
The previous few commits demonstrated once again that ignoring
programming errors is a bad idea.
Of the few ones that pass on errors, several violate the Error API.
The Error ** argument must be NULL, &error_abort, &error_fatal, or a
pointer to a variable containing NULL. Passing an argument of the
latter kind twice without clearing it in between is wrong: if the
first call sets an error, it no longer points to NULL for the second
call. ich9_pm_add_properties(), sparc32_ledma_realize(),
sparc32_dma_realize(), xilinx_axidma_realize(), xilinx_enet_realize()
are wrong that way.
When the one appropriate choice of argument is &error_abort, letting
users pick the argument is a bad idea.
Drop parameter @errp and assert the preconditions instead.
There's one exception to "duplicate property name is a programming
error": the way object_property_add() implements the magic (and
undocumented) "automatic arrayification". Don't drop @errp there.
Instead, rename object_property_add() to object_property_try_add(),
and add the obvious wrapper object_property_add().
Signed-off-by: Markus Armbruster <armbru@redhat.com>
Reviewed-by: Eric Blake <eblake@redhat.com>
Reviewed-by: Paolo Bonzini <pbonzini@redhat.com>
Message-Id: <20200505152926.18877-15-armbru@redhat.com>
[Two semantic rebase conflicts resolved]
2020-05-05 18:29:22 +03:00
|
|
|
new);
|
2017-09-13 16:23:58 +03:00
|
|
|
object_unref(new);
|
qdev: Convert bus-less devices to qdev_realize() with Coccinelle
All remaining conversions to qdev_realize() are for bus-less devices.
Coccinelle script:
// only correct for bus-less @dev!
@@
expression errp;
expression dev;
@@
- qdev_init_nofail(dev);
+ qdev_realize(dev, NULL, &error_fatal);
@ depends on !(file in "hw/core/qdev.c") && !(file in "hw/core/bus.c")@
expression errp;
expression dev;
symbol true;
@@
- object_property_set_bool(OBJECT(dev), true, "realized", errp);
+ qdev_realize(DEVICE(dev), NULL, errp);
@ depends on !(file in "hw/core/qdev.c") && !(file in "hw/core/bus.c")@
expression errp;
expression dev;
symbol true;
@@
- object_property_set_bool(dev, true, "realized", errp);
+ qdev_realize(DEVICE(dev), NULL, errp);
Note that Coccinelle chokes on ARMSSE typedef vs. macro in
hw/arm/armsse.c. Worked around by temporarily renaming the macro for
the spatch run.
Signed-off-by: Markus Armbruster <armbru@redhat.com>
Acked-by: Alistair Francis <alistair.francis@wdc.com>
Reviewed-by: Paolo Bonzini <pbonzini@redhat.com>
Message-Id: <20200610053247.1583243-57-armbru@redhat.com>
2020-06-10 08:32:45 +03:00
|
|
|
qdev_realize(dev, NULL, &error_fatal);
|
2017-09-13 16:23:58 +03:00
|
|
|
}
|
|
|
|
|
|
|
|
static void s390_create_virtio_net(BusState *bus, const char *name)
|
|
|
|
{
|
|
|
|
int i;
|
|
|
|
|
|
|
|
for (i = 0; i < nb_nics; i++) {
|
|
|
|
NICInfo *nd = &nd_table[i];
|
|
|
|
DeviceState *dev;
|
|
|
|
|
|
|
|
if (!nd->model) {
|
|
|
|
nd->model = g_strdup("virtio");
|
|
|
|
}
|
|
|
|
|
|
|
|
qemu_check_nic_model(nd, "virtio");
|
|
|
|
|
qdev: Convert uses of qdev_create() with Coccinelle
This is the transformation explained in the commit before previous.
Takes care of just one pattern that needs conversion. More to come in
this series.
Coccinelle script:
@ depends on !(file in "hw/arm/highbank.c")@
expression bus, type_name, dev, expr;
@@
- dev = qdev_create(bus, type_name);
+ dev = qdev_new(type_name);
... when != dev = expr
- qdev_init_nofail(dev);
+ qdev_realize_and_unref(dev, bus, &error_fatal);
@@
expression bus, type_name, dev, expr;
identifier DOWN;
@@
- dev = DOWN(qdev_create(bus, type_name));
+ dev = DOWN(qdev_new(type_name));
... when != dev = expr
- qdev_init_nofail(DEVICE(dev));
+ qdev_realize_and_unref(DEVICE(dev), bus, &error_fatal);
@@
expression bus, type_name, expr;
identifier dev;
@@
- DeviceState *dev = qdev_create(bus, type_name);
+ DeviceState *dev = qdev_new(type_name);
... when != dev = expr
- qdev_init_nofail(dev);
+ qdev_realize_and_unref(dev, bus, &error_fatal);
@@
expression bus, type_name, dev, expr, errp;
symbol true;
@@
- dev = qdev_create(bus, type_name);
+ dev = qdev_new(type_name);
... when != dev = expr
- object_property_set_bool(OBJECT(dev), true, "realized", errp);
+ qdev_realize_and_unref(dev, bus, errp);
@@
expression bus, type_name, expr, errp;
identifier dev;
symbol true;
@@
- DeviceState *dev = qdev_create(bus, type_name);
+ DeviceState *dev = qdev_new(type_name);
... when != dev = expr
- object_property_set_bool(OBJECT(dev), true, "realized", errp);
+ qdev_realize_and_unref(dev, bus, errp);
The first rule exempts hw/arm/highbank.c, because it matches along two
control flow paths there, with different @type_name. Covered by the
next commit's manual conversions.
Missing #include "qapi/error.h" added manually.
Signed-off-by: Markus Armbruster <armbru@redhat.com>
Reviewed-by: Paolo Bonzini <pbonzini@redhat.com>
Message-Id: <20200610053247.1583243-10-armbru@redhat.com>
[Conflicts in hw/misc/empty_slot.c and hw/sparc/leon3.c resolved]
2020-06-10 08:31:58 +03:00
|
|
|
dev = qdev_new(name);
|
2017-09-13 16:23:58 +03:00
|
|
|
qdev_set_nic_properties(dev, nd);
|
qdev: Convert uses of qdev_create() with Coccinelle
This is the transformation explained in the commit before previous.
Takes care of just one pattern that needs conversion. More to come in
this series.
Coccinelle script:
@ depends on !(file in "hw/arm/highbank.c")@
expression bus, type_name, dev, expr;
@@
- dev = qdev_create(bus, type_name);
+ dev = qdev_new(type_name);
... when != dev = expr
- qdev_init_nofail(dev);
+ qdev_realize_and_unref(dev, bus, &error_fatal);
@@
expression bus, type_name, dev, expr;
identifier DOWN;
@@
- dev = DOWN(qdev_create(bus, type_name));
+ dev = DOWN(qdev_new(type_name));
... when != dev = expr
- qdev_init_nofail(DEVICE(dev));
+ qdev_realize_and_unref(DEVICE(dev), bus, &error_fatal);
@@
expression bus, type_name, expr;
identifier dev;
@@
- DeviceState *dev = qdev_create(bus, type_name);
+ DeviceState *dev = qdev_new(type_name);
... when != dev = expr
- qdev_init_nofail(dev);
+ qdev_realize_and_unref(dev, bus, &error_fatal);
@@
expression bus, type_name, dev, expr, errp;
symbol true;
@@
- dev = qdev_create(bus, type_name);
+ dev = qdev_new(type_name);
... when != dev = expr
- object_property_set_bool(OBJECT(dev), true, "realized", errp);
+ qdev_realize_and_unref(dev, bus, errp);
@@
expression bus, type_name, expr, errp;
identifier dev;
symbol true;
@@
- DeviceState *dev = qdev_create(bus, type_name);
+ DeviceState *dev = qdev_new(type_name);
... when != dev = expr
- object_property_set_bool(OBJECT(dev), true, "realized", errp);
+ qdev_realize_and_unref(dev, bus, errp);
The first rule exempts hw/arm/highbank.c, because it matches along two
control flow paths there, with different @type_name. Covered by the
next commit's manual conversions.
Missing #include "qapi/error.h" added manually.
Signed-off-by: Markus Armbruster <armbru@redhat.com>
Reviewed-by: Paolo Bonzini <pbonzini@redhat.com>
Message-Id: <20200610053247.1583243-10-armbru@redhat.com>
[Conflicts in hw/misc/empty_slot.c and hw/sparc/leon3.c resolved]
2020-06-10 08:31:58 +03:00
|
|
|
qdev_realize_and_unref(dev, bus, &error_fatal);
|
2017-09-13 16:23:58 +03:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
hw/s390x: Allow to configure the consoles with the "-serial" parameter
The consoles ("sclpconsole" and "sclplmconsole") can only be configured
with "-device" and "-chardev" so far. Other machines use the convenience
option "-serial" to configure the default consoles, even for virtual
consoles like spapr-vty on the pseries machine. So let's support this
option on s390x, too. This way we can easily enable the serial console
here again with "-nodefaults", for example:
qemu-system-s390x -no-shutdown -nographic -nodefaults -serial mon:stdio
... which is way shorter than typing:
qemu-system-s390x -no-shutdown -nographic -nodefaults \
-chardev stdio,id=c1,mux=on -device sclpconsole,chardev=c1 \
-mon chardev=c1
The -serial parameter can also be used if you only want to see the QEMU
monitor on stdio without using -nodefaults, but not the console output.
That's something that is pretty impossible with the current code today:
qemu-system-s390x -no-shutdown -nographic -serial none
While we're at it, this patch also maps the second -serial option to the
"sclplmconsole", so that there is now an easy way to configure this second
console on s390x, too, for example:
qemu-system-s390x -no-shutdown -nographic -serial null -serial mon:stdio
Additionally, the new code is also smaller than the old one and we have
less s390x-specific code in vl.c :-)
I've also checked that migration still works as expected by migrating
a guest with console output back and forth between a qemu-system-s390x
that has this patch and an instance without this patch.
Signed-off-by: Thomas Huth <thuth@redhat.com>
Message-Id: <1524754794-28005-1-git-send-email-thuth@redhat.com>
Reviewed-by: David Hildenbrand <david@redhat.com>
Signed-off-by: Cornelia Huck <cohuck@redhat.com>
2018-04-26 17:59:54 +03:00
|
|
|
static void s390_create_sclpconsole(const char *type, Chardev *chardev)
|
|
|
|
{
|
|
|
|
DeviceState *dev;
|
|
|
|
|
qdev: Convert uses of qdev_create() with Coccinelle
This is the transformation explained in the commit before previous.
Takes care of just one pattern that needs conversion. More to come in
this series.
Coccinelle script:
@ depends on !(file in "hw/arm/highbank.c")@
expression bus, type_name, dev, expr;
@@
- dev = qdev_create(bus, type_name);
+ dev = qdev_new(type_name);
... when != dev = expr
- qdev_init_nofail(dev);
+ qdev_realize_and_unref(dev, bus, &error_fatal);
@@
expression bus, type_name, dev, expr;
identifier DOWN;
@@
- dev = DOWN(qdev_create(bus, type_name));
+ dev = DOWN(qdev_new(type_name));
... when != dev = expr
- qdev_init_nofail(DEVICE(dev));
+ qdev_realize_and_unref(DEVICE(dev), bus, &error_fatal);
@@
expression bus, type_name, expr;
identifier dev;
@@
- DeviceState *dev = qdev_create(bus, type_name);
+ DeviceState *dev = qdev_new(type_name);
... when != dev = expr
- qdev_init_nofail(dev);
+ qdev_realize_and_unref(dev, bus, &error_fatal);
@@
expression bus, type_name, dev, expr, errp;
symbol true;
@@
- dev = qdev_create(bus, type_name);
+ dev = qdev_new(type_name);
... when != dev = expr
- object_property_set_bool(OBJECT(dev), true, "realized", errp);
+ qdev_realize_and_unref(dev, bus, errp);
@@
expression bus, type_name, expr, errp;
identifier dev;
symbol true;
@@
- DeviceState *dev = qdev_create(bus, type_name);
+ DeviceState *dev = qdev_new(type_name);
... when != dev = expr
- object_property_set_bool(OBJECT(dev), true, "realized", errp);
+ qdev_realize_and_unref(dev, bus, errp);
The first rule exempts hw/arm/highbank.c, because it matches along two
control flow paths there, with different @type_name. Covered by the
next commit's manual conversions.
Missing #include "qapi/error.h" added manually.
Signed-off-by: Markus Armbruster <armbru@redhat.com>
Reviewed-by: Paolo Bonzini <pbonzini@redhat.com>
Message-Id: <20200610053247.1583243-10-armbru@redhat.com>
[Conflicts in hw/misc/empty_slot.c and hw/sparc/leon3.c resolved]
2020-06-10 08:31:58 +03:00
|
|
|
dev = qdev_new(type);
|
hw/s390x: Allow to configure the consoles with the "-serial" parameter
The consoles ("sclpconsole" and "sclplmconsole") can only be configured
with "-device" and "-chardev" so far. Other machines use the convenience
option "-serial" to configure the default consoles, even for virtual
consoles like spapr-vty on the pseries machine. So let's support this
option on s390x, too. This way we can easily enable the serial console
here again with "-nodefaults", for example:
qemu-system-s390x -no-shutdown -nographic -nodefaults -serial mon:stdio
... which is way shorter than typing:
qemu-system-s390x -no-shutdown -nographic -nodefaults \
-chardev stdio,id=c1,mux=on -device sclpconsole,chardev=c1 \
-mon chardev=c1
The -serial parameter can also be used if you only want to see the QEMU
monitor on stdio without using -nodefaults, but not the console output.
That's something that is pretty impossible with the current code today:
qemu-system-s390x -no-shutdown -nographic -serial none
While we're at it, this patch also maps the second -serial option to the
"sclplmconsole", so that there is now an easy way to configure this second
console on s390x, too, for example:
qemu-system-s390x -no-shutdown -nographic -serial null -serial mon:stdio
Additionally, the new code is also smaller than the old one and we have
less s390x-specific code in vl.c :-)
I've also checked that migration still works as expected by migrating
a guest with console output back and forth between a qemu-system-s390x
that has this patch and an instance without this patch.
Signed-off-by: Thomas Huth <thuth@redhat.com>
Message-Id: <1524754794-28005-1-git-send-email-thuth@redhat.com>
Reviewed-by: David Hildenbrand <david@redhat.com>
Signed-off-by: Cornelia Huck <cohuck@redhat.com>
2018-04-26 17:59:54 +03:00
|
|
|
qdev_prop_set_chr(dev, "chardev", chardev);
|
qdev: Convert uses of qdev_create() with Coccinelle
This is the transformation explained in the commit before previous.
Takes care of just one pattern that needs conversion. More to come in
this series.
Coccinelle script:
@ depends on !(file in "hw/arm/highbank.c")@
expression bus, type_name, dev, expr;
@@
- dev = qdev_create(bus, type_name);
+ dev = qdev_new(type_name);
... when != dev = expr
- qdev_init_nofail(dev);
+ qdev_realize_and_unref(dev, bus, &error_fatal);
@@
expression bus, type_name, dev, expr;
identifier DOWN;
@@
- dev = DOWN(qdev_create(bus, type_name));
+ dev = DOWN(qdev_new(type_name));
... when != dev = expr
- qdev_init_nofail(DEVICE(dev));
+ qdev_realize_and_unref(DEVICE(dev), bus, &error_fatal);
@@
expression bus, type_name, expr;
identifier dev;
@@
- DeviceState *dev = qdev_create(bus, type_name);
+ DeviceState *dev = qdev_new(type_name);
... when != dev = expr
- qdev_init_nofail(dev);
+ qdev_realize_and_unref(dev, bus, &error_fatal);
@@
expression bus, type_name, dev, expr, errp;
symbol true;
@@
- dev = qdev_create(bus, type_name);
+ dev = qdev_new(type_name);
... when != dev = expr
- object_property_set_bool(OBJECT(dev), true, "realized", errp);
+ qdev_realize_and_unref(dev, bus, errp);
@@
expression bus, type_name, expr, errp;
identifier dev;
symbol true;
@@
- DeviceState *dev = qdev_create(bus, type_name);
+ DeviceState *dev = qdev_new(type_name);
... when != dev = expr
- object_property_set_bool(OBJECT(dev), true, "realized", errp);
+ qdev_realize_and_unref(dev, bus, errp);
The first rule exempts hw/arm/highbank.c, because it matches along two
control flow paths there, with different @type_name. Covered by the
next commit's manual conversions.
Missing #include "qapi/error.h" added manually.
Signed-off-by: Markus Armbruster <armbru@redhat.com>
Reviewed-by: Paolo Bonzini <pbonzini@redhat.com>
Message-Id: <20200610053247.1583243-10-armbru@redhat.com>
[Conflicts in hw/misc/empty_slot.c and hw/sparc/leon3.c resolved]
2020-06-10 08:31:58 +03:00
|
|
|
qdev_realize_and_unref(dev, sclp_get_event_facility_bus(), &error_fatal);
|
hw/s390x: Allow to configure the consoles with the "-serial" parameter
The consoles ("sclpconsole" and "sclplmconsole") can only be configured
with "-device" and "-chardev" so far. Other machines use the convenience
option "-serial" to configure the default consoles, even for virtual
consoles like spapr-vty on the pseries machine. So let's support this
option on s390x, too. This way we can easily enable the serial console
here again with "-nodefaults", for example:
qemu-system-s390x -no-shutdown -nographic -nodefaults -serial mon:stdio
... which is way shorter than typing:
qemu-system-s390x -no-shutdown -nographic -nodefaults \
-chardev stdio,id=c1,mux=on -device sclpconsole,chardev=c1 \
-mon chardev=c1
The -serial parameter can also be used if you only want to see the QEMU
monitor on stdio without using -nodefaults, but not the console output.
That's something that is pretty impossible with the current code today:
qemu-system-s390x -no-shutdown -nographic -serial none
While we're at it, this patch also maps the second -serial option to the
"sclplmconsole", so that there is now an easy way to configure this second
console on s390x, too, for example:
qemu-system-s390x -no-shutdown -nographic -serial null -serial mon:stdio
Additionally, the new code is also smaller than the old one and we have
less s390x-specific code in vl.c :-)
I've also checked that migration still works as expected by migrating
a guest with console output back and forth between a qemu-system-s390x
that has this patch and an instance without this patch.
Signed-off-by: Thomas Huth <thuth@redhat.com>
Message-Id: <1524754794-28005-1-git-send-email-thuth@redhat.com>
Reviewed-by: David Hildenbrand <david@redhat.com>
Signed-off-by: Cornelia Huck <cohuck@redhat.com>
2018-04-26 17:59:54 +03:00
|
|
|
}
|
|
|
|
|
2015-05-29 16:01:55 +03:00
|
|
|
static void ccw_init(MachineState *machine)
|
|
|
|
{
|
2023-05-11 15:50:36 +03:00
|
|
|
MachineClass *mc = MACHINE_GET_CLASS(machine);
|
2013-01-24 10:08:56 +04:00
|
|
|
int ret;
|
|
|
|
VirtualCssBus *css_bus;
|
2017-09-28 16:18:31 +03:00
|
|
|
DeviceState *dev;
|
2014-08-28 19:25:33 +04:00
|
|
|
|
2015-05-29 14:53:08 +03:00
|
|
|
s390_sclp_init();
|
2019-04-17 14:31:42 +03:00
|
|
|
/* init memory + setup max page size. Required for the CPU model */
|
2020-02-19 19:09:12 +03:00
|
|
|
s390_memory_init(machine->ram);
|
2013-01-24 10:08:56 +04:00
|
|
|
|
2017-07-06 18:21:52 +03:00
|
|
|
/* init CPUs (incl. CPU model) early so s390_has_feature() works */
|
2017-06-14 08:16:20 +03:00
|
|
|
s390_init_cpus(machine);
|
|
|
|
|
s390: Recognize confidential-guest-support option
At least some s390 cpu models support "Protected Virtualization" (PV),
a mechanism to protect guests from eavesdropping by a compromised
hypervisor.
This is similar in function to other mechanisms like AMD's SEV and
POWER's PEF, which are controlled by the "confidential-guest-support"
machine option. s390 is a slightly special case, because we already
supported PV, simply by using a CPU model with the required feature
(S390_FEAT_UNPACK).
To integrate this with the option used by other platforms, we
implement the following compromise:
- When the confidential-guest-support option is set, s390 will
recognize it, verify that the CPU can support PV (failing if not)
and set virtio default options necessary for encrypted or protected
guests, as on other platforms. i.e. if confidential-guest-support
is set, we will either create a guest capable of entering PV mode,
or fail outright.
- If confidential-guest-support is not set, guests might still be
able to enter PV mode, if the CPU has the right model. This may be
a little surprising, but shouldn't actually be harmful.
To start a guest supporting Protected Virtualization using the new
option use the command line arguments:
-object s390-pv-guest,id=pv0 -machine confidential-guest-support=pv0
Signed-off-by: David Gibson <david@gibson.dropbear.id.au>
Tested-by: Christian Borntraeger <borntraeger@de.ibm.com>
Reviewed-by: Christian Borntraeger <borntraeger@de.ibm.com>
2020-07-23 07:36:45 +03:00
|
|
|
/* Need CPU model to be determined before we can set up PV */
|
|
|
|
s390_pv_init(machine->cgs, &error_fatal);
|
|
|
|
|
2016-12-02 11:37:48 +03:00
|
|
|
s390_flic_init();
|
|
|
|
|
2017-09-28 23:36:54 +03:00
|
|
|
/* init the SIGP facility */
|
|
|
|
s390_init_sigp();
|
|
|
|
|
2018-10-10 20:03:06 +03:00
|
|
|
/* create AP bridge and bus(es) */
|
|
|
|
s390_init_ap();
|
|
|
|
|
2013-01-24 10:08:56 +04:00
|
|
|
/* get a BUS */
|
|
|
|
css_bus = virtual_css_bus_init();
|
2014-05-07 18:42:57 +04:00
|
|
|
s390_init_ipl_dev(machine->kernel_filename, machine->kernel_cmdline,
|
2020-10-26 17:30:25 +03:00
|
|
|
machine->initrd_filename,
|
|
|
|
machine->firmware ?: "s390-ccw.img",
|
2016-10-21 19:17:08 +03:00
|
|
|
"s390-netboot.img", true);
|
2013-01-24 10:08:56 +04:00
|
|
|
|
qdev: Convert uses of qdev_create() with Coccinelle
This is the transformation explained in the commit before previous.
Takes care of just one pattern that needs conversion. More to come in
this series.
Coccinelle script:
@ depends on !(file in "hw/arm/highbank.c")@
expression bus, type_name, dev, expr;
@@
- dev = qdev_create(bus, type_name);
+ dev = qdev_new(type_name);
... when != dev = expr
- qdev_init_nofail(dev);
+ qdev_realize_and_unref(dev, bus, &error_fatal);
@@
expression bus, type_name, dev, expr;
identifier DOWN;
@@
- dev = DOWN(qdev_create(bus, type_name));
+ dev = DOWN(qdev_new(type_name));
... when != dev = expr
- qdev_init_nofail(DEVICE(dev));
+ qdev_realize_and_unref(DEVICE(dev), bus, &error_fatal);
@@
expression bus, type_name, expr;
identifier dev;
@@
- DeviceState *dev = qdev_create(bus, type_name);
+ DeviceState *dev = qdev_new(type_name);
... when != dev = expr
- qdev_init_nofail(dev);
+ qdev_realize_and_unref(dev, bus, &error_fatal);
@@
expression bus, type_name, dev, expr, errp;
symbol true;
@@
- dev = qdev_create(bus, type_name);
+ dev = qdev_new(type_name);
... when != dev = expr
- object_property_set_bool(OBJECT(dev), true, "realized", errp);
+ qdev_realize_and_unref(dev, bus, errp);
@@
expression bus, type_name, expr, errp;
identifier dev;
symbol true;
@@
- DeviceState *dev = qdev_create(bus, type_name);
+ DeviceState *dev = qdev_new(type_name);
... when != dev = expr
- object_property_set_bool(OBJECT(dev), true, "realized", errp);
+ qdev_realize_and_unref(dev, bus, errp);
The first rule exempts hw/arm/highbank.c, because it matches along two
control flow paths there, with different @type_name. Covered by the
next commit's manual conversions.
Missing #include "qapi/error.h" added manually.
Signed-off-by: Markus Armbruster <armbru@redhat.com>
Reviewed-by: Paolo Bonzini <pbonzini@redhat.com>
Message-Id: <20200610053247.1583243-10-armbru@redhat.com>
[Conflicts in hw/misc/empty_slot.c and hw/sparc/leon3.c resolved]
2020-06-10 08:31:58 +03:00
|
|
|
dev = qdev_new(TYPE_S390_PCI_HOST_BRIDGE);
|
2017-09-28 16:18:31 +03:00
|
|
|
object_property_add_child(qdev_get_machine(), TYPE_S390_PCI_HOST_BRIDGE,
|
qom: Drop parameter @errp of object_property_add() & friends
The only way object_property_add() can fail is when a property with
the same name already exists. Since our property names are all
hardcoded, failure is a programming error, and the appropriate way to
handle it is passing &error_abort.
Same for its variants, except for object_property_add_child(), which
additionally fails when the child already has a parent. Parentage is
also under program control, so this is a programming error, too.
We have a bit over 500 callers. Almost half of them pass
&error_abort, slightly fewer ignore errors, one test case handles
errors, and the remaining few callers pass them to their own callers.
The previous few commits demonstrated once again that ignoring
programming errors is a bad idea.
Of the few ones that pass on errors, several violate the Error API.
The Error ** argument must be NULL, &error_abort, &error_fatal, or a
pointer to a variable containing NULL. Passing an argument of the
latter kind twice without clearing it in between is wrong: if the
first call sets an error, it no longer points to NULL for the second
call. ich9_pm_add_properties(), sparc32_ledma_realize(),
sparc32_dma_realize(), xilinx_axidma_realize(), xilinx_enet_realize()
are wrong that way.
When the one appropriate choice of argument is &error_abort, letting
users pick the argument is a bad idea.
Drop parameter @errp and assert the preconditions instead.
There's one exception to "duplicate property name is a programming
error": the way object_property_add() implements the magic (and
undocumented) "automatic arrayification". Don't drop @errp there.
Instead, rename object_property_add() to object_property_try_add(),
and add the obvious wrapper object_property_add().
Signed-off-by: Markus Armbruster <armbru@redhat.com>
Reviewed-by: Eric Blake <eblake@redhat.com>
Reviewed-by: Paolo Bonzini <pbonzini@redhat.com>
Message-Id: <20200505152926.18877-15-armbru@redhat.com>
[Two semantic rebase conflicts resolved]
2020-05-05 18:29:22 +03:00
|
|
|
OBJECT(dev));
|
sysbus: Convert to sysbus_realize() etc. with Coccinelle
Convert from qdev_realize(), qdev_realize_and_unref() with null @bus
argument to sysbus_realize(), sysbus_realize_and_unref().
Coccinelle script:
@@
expression dev, errp;
@@
- qdev_realize(DEVICE(dev), NULL, errp);
+ sysbus_realize(SYS_BUS_DEVICE(dev), errp);
@@
expression sysbus_dev, dev, errp;
@@
+ sysbus_dev = SYS_BUS_DEVICE(dev);
- qdev_realize_and_unref(dev, NULL, errp);
+ sysbus_realize_and_unref(sysbus_dev, errp);
- sysbus_dev = SYS_BUS_DEVICE(dev);
@@
expression sysbus_dev, dev, errp;
expression expr;
@@
sysbus_dev = SYS_BUS_DEVICE(dev);
... when != dev = expr;
- qdev_realize_and_unref(dev, NULL, errp);
+ sysbus_realize_and_unref(sysbus_dev, errp);
@@
expression dev, errp;
@@
- qdev_realize_and_unref(DEVICE(dev), NULL, errp);
+ sysbus_realize_and_unref(SYS_BUS_DEVICE(dev), errp);
@@
expression dev, errp;
@@
- qdev_realize_and_unref(dev, NULL, errp);
+ sysbus_realize_and_unref(SYS_BUS_DEVICE(dev), errp);
Whitespace changes minimized manually.
Signed-off-by: Markus Armbruster <armbru@redhat.com>
Acked-by: Alistair Francis <alistair.francis@wdc.com>
Reviewed-by: Philippe Mathieu-Daudé <philmd@redhat.com>
Reviewed-by: Paolo Bonzini <pbonzini@redhat.com>
Message-Id: <20200610053247.1583243-46-armbru@redhat.com>
[Conflicts in hw/misc/empty_slot.c and hw/sparc/leon3.c resolved]
2020-06-10 08:32:34 +03:00
|
|
|
sysbus_realize_and_unref(SYS_BUS_DEVICE(dev), &error_fatal);
|
2015-01-09 11:04:38 +03:00
|
|
|
|
2013-01-24 10:08:56 +04:00
|
|
|
/* register hypercalls */
|
|
|
|
virtio_ccw_register_hcalls();
|
|
|
|
|
2017-08-18 14:43:51 +03:00
|
|
|
s390_enable_css_support(s390_cpu_addr2state(0));
|
2018-07-23 19:32:21 +03:00
|
|
|
|
|
|
|
ret = css_create_css_image(VIRTUAL_CSSID, true);
|
2017-12-06 17:44:38 +03:00
|
|
|
|
2013-01-24 10:08:56 +04:00
|
|
|
assert(ret == 0);
|
2017-10-04 14:01:09 +03:00
|
|
|
if (css_migration_enabled()) {
|
|
|
|
css_register_vmstate();
|
|
|
|
}
|
2013-01-24 10:08:56 +04:00
|
|
|
|
|
|
|
/* Create VirtIO network adapters */
|
2023-05-11 15:50:36 +03:00
|
|
|
s390_create_virtio_net(BUS(css_bus), mc->default_nic);
|
2015-03-09 17:56:08 +03:00
|
|
|
|
hw/s390x: Allow to configure the consoles with the "-serial" parameter
The consoles ("sclpconsole" and "sclplmconsole") can only be configured
with "-device" and "-chardev" so far. Other machines use the convenience
option "-serial" to configure the default consoles, even for virtual
consoles like spapr-vty on the pseries machine. So let's support this
option on s390x, too. This way we can easily enable the serial console
here again with "-nodefaults", for example:
qemu-system-s390x -no-shutdown -nographic -nodefaults -serial mon:stdio
... which is way shorter than typing:
qemu-system-s390x -no-shutdown -nographic -nodefaults \
-chardev stdio,id=c1,mux=on -device sclpconsole,chardev=c1 \
-mon chardev=c1
The -serial parameter can also be used if you only want to see the QEMU
monitor on stdio without using -nodefaults, but not the console output.
That's something that is pretty impossible with the current code today:
qemu-system-s390x -no-shutdown -nographic -serial none
While we're at it, this patch also maps the second -serial option to the
"sclplmconsole", so that there is now an easy way to configure this second
console on s390x, too, for example:
qemu-system-s390x -no-shutdown -nographic -serial null -serial mon:stdio
Additionally, the new code is also smaller than the old one and we have
less s390x-specific code in vl.c :-)
I've also checked that migration still works as expected by migrating
a guest with console output back and forth between a qemu-system-s390x
that has this patch and an instance without this patch.
Signed-off-by: Thomas Huth <thuth@redhat.com>
Message-Id: <1524754794-28005-1-git-send-email-thuth@redhat.com>
Reviewed-by: David Hildenbrand <david@redhat.com>
Signed-off-by: Cornelia Huck <cohuck@redhat.com>
2018-04-26 17:59:54 +03:00
|
|
|
/* init consoles */
|
|
|
|
if (serial_hd(0)) {
|
|
|
|
s390_create_sclpconsole("sclpconsole", serial_hd(0));
|
|
|
|
}
|
|
|
|
if (serial_hd(1)) {
|
|
|
|
s390_create_sclpconsole("sclplmconsole", serial_hd(1));
|
|
|
|
}
|
|
|
|
|
2018-06-27 16:44:04 +03:00
|
|
|
/* init the TOD clock */
|
|
|
|
s390_init_tod();
|
2013-01-24 10:08:56 +04:00
|
|
|
}
|
|
|
|
|
2016-03-04 20:34:33 +03:00
|
|
|
static void s390_cpu_plug(HotplugHandler *hotplug_dev,
|
|
|
|
DeviceState *dev, Error **errp)
|
|
|
|
{
|
2017-09-13 16:24:13 +03:00
|
|
|
MachineState *ms = MACHINE(hotplug_dev);
|
2016-03-04 20:34:33 +03:00
|
|
|
S390CPU *cpu = S390_CPU(dev);
|
2017-09-13 16:24:13 +03:00
|
|
|
|
|
|
|
g_assert(!ms->possible_cpus->cpus[cpu->env.core_id].cpu);
|
|
|
|
ms->possible_cpus->cpus[cpu->env.core_id].cpu = OBJECT(dev);
|
2017-09-28 16:46:06 +03:00
|
|
|
|
|
|
|
if (dev->hotplugged) {
|
|
|
|
raise_irq_cpu_hotplug();
|
|
|
|
}
|
2016-03-04 20:34:33 +03:00
|
|
|
}
|
|
|
|
|
2018-04-24 13:18:59 +03:00
|
|
|
static inline void s390_do_cpu_ipl(CPUState *cs, run_on_cpu_data arg)
|
|
|
|
{
|
|
|
|
S390CPU *cpu = S390_CPU(cs);
|
|
|
|
|
|
|
|
s390_ipl_prepare_cpu(cpu);
|
|
|
|
s390_cpu_set_state(S390_CPU_STATE_OPERATING, cpu);
|
|
|
|
}
|
|
|
|
|
2020-03-23 11:36:06 +03:00
|
|
|
static void s390_machine_unprotect(S390CcwMachineState *ms)
|
|
|
|
{
|
2023-05-10 13:55:31 +03:00
|
|
|
if (!s390_pv_vm_try_disable_async(ms)) {
|
2023-02-14 19:30:35 +03:00
|
|
|
s390_pv_vm_disable();
|
|
|
|
}
|
2020-03-23 11:36:06 +03:00
|
|
|
ms->pv = false;
|
2020-03-19 16:19:09 +03:00
|
|
|
migrate_del_blocker(pv_mig_blocker);
|
|
|
|
error_free_or_abort(&pv_mig_blocker);
|
2020-06-26 10:22:32 +03:00
|
|
|
ram_block_discard_disable(false);
|
2020-03-23 11:36:06 +03:00
|
|
|
}
|
|
|
|
|
|
|
|
static int s390_machine_protect(S390CcwMachineState *ms)
|
|
|
|
{
|
2020-03-19 16:19:09 +03:00
|
|
|
Error *local_err = NULL;
|
2020-03-23 11:36:06 +03:00
|
|
|
int rc;
|
|
|
|
|
2020-03-19 16:19:10 +03:00
|
|
|
/*
|
2020-06-26 10:22:32 +03:00
|
|
|
* Discarding of memory in RAM blocks does not work as expected with
|
|
|
|
* protected VMs. Sharing and unsharing pages would be required. Disable
|
|
|
|
* it for now, until until we have a solution to make at least Linux
|
|
|
|
* guests either support it (e.g., virtio-balloon) or fail gracefully.
|
2020-03-19 16:19:10 +03:00
|
|
|
*/
|
2020-06-26 10:22:32 +03:00
|
|
|
rc = ram_block_discard_disable(true);
|
|
|
|
if (rc) {
|
|
|
|
error_report("protected VMs: cannot disable RAM discard");
|
|
|
|
return rc;
|
|
|
|
}
|
|
|
|
|
2020-03-19 16:19:09 +03:00
|
|
|
error_setg(&pv_mig_blocker,
|
2022-11-11 21:17:33 +03:00
|
|
|
"protected VMs are currently not migratable.");
|
2020-03-19 16:19:09 +03:00
|
|
|
rc = migrate_add_blocker(pv_mig_blocker, &local_err);
|
|
|
|
if (rc) {
|
2020-06-26 10:22:32 +03:00
|
|
|
ram_block_discard_disable(false);
|
2020-03-19 16:19:09 +03:00
|
|
|
error_report_err(local_err);
|
|
|
|
error_free_or_abort(&pv_mig_blocker);
|
|
|
|
return rc;
|
|
|
|
}
|
|
|
|
|
2020-03-23 11:36:06 +03:00
|
|
|
/* Create SE VM */
|
|
|
|
rc = s390_pv_vm_enable();
|
|
|
|
if (rc) {
|
2020-06-26 10:22:32 +03:00
|
|
|
ram_block_discard_disable(false);
|
2020-03-19 16:19:09 +03:00
|
|
|
migrate_del_blocker(pv_mig_blocker);
|
|
|
|
error_free_or_abort(&pv_mig_blocker);
|
2020-03-23 11:36:06 +03:00
|
|
|
return rc;
|
|
|
|
}
|
|
|
|
|
|
|
|
ms->pv = true;
|
|
|
|
|
2022-10-17 11:38:19 +03:00
|
|
|
/* Will return 0 if API is not available since it's not vital */
|
|
|
|
rc = s390_pv_query_info();
|
|
|
|
if (rc) {
|
|
|
|
goto out_err;
|
|
|
|
}
|
|
|
|
|
2020-03-23 11:36:06 +03:00
|
|
|
/* Set SE header and unpack */
|
|
|
|
rc = s390_ipl_prepare_pv_header();
|
|
|
|
if (rc) {
|
|
|
|
goto out_err;
|
|
|
|
}
|
|
|
|
|
|
|
|
/* Decrypt image */
|
|
|
|
rc = s390_ipl_pv_unpack();
|
|
|
|
if (rc) {
|
|
|
|
goto out_err;
|
|
|
|
}
|
|
|
|
|
|
|
|
/* Verify integrity */
|
|
|
|
rc = s390_pv_verify();
|
|
|
|
if (rc) {
|
|
|
|
goto out_err;
|
|
|
|
}
|
|
|
|
return rc;
|
|
|
|
|
|
|
|
out_err:
|
|
|
|
s390_machine_unprotect(ms);
|
|
|
|
return rc;
|
|
|
|
}
|
|
|
|
|
|
|
|
static void s390_pv_prepare_reset(S390CcwMachineState *ms)
|
|
|
|
{
|
|
|
|
CPUState *cs;
|
|
|
|
|
|
|
|
if (!s390_is_pv()) {
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
/* Unsharing requires all cpus to be stopped */
|
|
|
|
CPU_FOREACH(cs) {
|
|
|
|
s390_cpu_set_state(S390_CPU_STATE_STOPPED, S390_CPU(cs));
|
|
|
|
}
|
|
|
|
s390_pv_unshare();
|
2020-05-05 15:41:59 +03:00
|
|
|
s390_pv_prep_reset();
|
2020-03-23 11:36:06 +03:00
|
|
|
}
|
|
|
|
|
2022-10-25 03:43:17 +03:00
|
|
|
static void s390_machine_reset(MachineState *machine, ShutdownCause reason)
|
2017-09-13 16:23:58 +03:00
|
|
|
{
|
2020-03-23 11:36:06 +03:00
|
|
|
S390CcwMachineState *ms = S390_CCW_MACHINE(machine);
|
2018-04-24 13:18:59 +03:00
|
|
|
enum s390_reset reset_type;
|
|
|
|
CPUState *cs, *t;
|
2020-03-23 11:36:06 +03:00
|
|
|
S390CPU *cpu;
|
2017-09-13 16:23:58 +03:00
|
|
|
|
2018-04-24 13:18:59 +03:00
|
|
|
/* get the reset parameters, reset them once done */
|
|
|
|
s390_ipl_get_reset_request(&cs, &reset_type);
|
|
|
|
|
|
|
|
/* all CPUs are paused and synchronized at this point */
|
2017-09-13 16:23:58 +03:00
|
|
|
s390_cmma_reset();
|
|
|
|
|
2020-03-23 11:36:06 +03:00
|
|
|
cpu = S390_CPU(cs);
|
|
|
|
|
2018-04-24 13:18:59 +03:00
|
|
|
switch (reset_type) {
|
|
|
|
case S390_RESET_EXTERNAL:
|
|
|
|
case S390_RESET_REIPL:
|
2020-03-23 11:36:06 +03:00
|
|
|
if (s390_is_pv()) {
|
|
|
|
s390_machine_unprotect(ms);
|
|
|
|
}
|
|
|
|
|
2022-10-25 03:43:17 +03:00
|
|
|
qemu_devices_reset(reason);
|
2018-04-24 13:18:59 +03:00
|
|
|
s390_crypto_reset();
|
|
|
|
|
|
|
|
/* configure and start the ipl CPU only */
|
|
|
|
run_on_cpu(cs, s390_do_cpu_ipl, RUN_ON_CPU_NULL);
|
|
|
|
break;
|
|
|
|
case S390_RESET_MODIFIED_CLEAR:
|
2020-03-23 11:36:06 +03:00
|
|
|
/*
|
2022-11-11 21:17:33 +03:00
|
|
|
* Subsystem reset needs to be done before we unshare memory
|
2020-03-23 11:36:06 +03:00
|
|
|
* and lose access to VIRTIO structures in guest memory.
|
|
|
|
*/
|
|
|
|
subsystem_reset();
|
|
|
|
s390_crypto_reset();
|
|
|
|
s390_pv_prepare_reset(ms);
|
2018-04-24 13:18:59 +03:00
|
|
|
CPU_FOREACH(t) {
|
|
|
|
run_on_cpu(t, s390_do_cpu_full_reset, RUN_ON_CPU_NULL);
|
|
|
|
}
|
|
|
|
run_on_cpu(cs, s390_do_cpu_load_normal, RUN_ON_CPU_NULL);
|
|
|
|
break;
|
|
|
|
case S390_RESET_LOAD_NORMAL:
|
2020-03-23 11:36:06 +03:00
|
|
|
/*
|
2022-11-11 21:17:33 +03:00
|
|
|
* Subsystem reset needs to be done before we unshare memory
|
2020-03-23 11:36:06 +03:00
|
|
|
* and lose access to VIRTIO structures in guest memory.
|
|
|
|
*/
|
|
|
|
subsystem_reset();
|
|
|
|
s390_pv_prepare_reset(ms);
|
2018-04-24 13:18:59 +03:00
|
|
|
CPU_FOREACH(t) {
|
2019-11-27 20:50:41 +03:00
|
|
|
if (t == cs) {
|
|
|
|
continue;
|
|
|
|
}
|
2018-04-24 13:18:59 +03:00
|
|
|
run_on_cpu(t, s390_do_cpu_reset, RUN_ON_CPU_NULL);
|
|
|
|
}
|
|
|
|
run_on_cpu(cs, s390_do_cpu_initial_reset, RUN_ON_CPU_NULL);
|
2020-03-23 11:36:06 +03:00
|
|
|
run_on_cpu(cs, s390_do_cpu_load_normal, RUN_ON_CPU_NULL);
|
|
|
|
break;
|
|
|
|
case S390_RESET_PV: /* Subcode 10 */
|
|
|
|
subsystem_reset();
|
|
|
|
s390_crypto_reset();
|
|
|
|
|
|
|
|
CPU_FOREACH(t) {
|
|
|
|
if (t == cs) {
|
|
|
|
continue;
|
|
|
|
}
|
|
|
|
run_on_cpu(t, s390_do_cpu_full_reset, RUN_ON_CPU_NULL);
|
|
|
|
}
|
|
|
|
run_on_cpu(cs, s390_do_cpu_reset, RUN_ON_CPU_NULL);
|
|
|
|
|
|
|
|
if (s390_machine_protect(ms)) {
|
2020-04-06 13:01:58 +03:00
|
|
|
s390_pv_inject_reset_error(cs);
|
2020-03-23 11:36:06 +03:00
|
|
|
/*
|
|
|
|
* Continue after the diag308 so the guest knows something
|
|
|
|
* went wrong.
|
|
|
|
*/
|
|
|
|
s390_cpu_set_state(S390_CPU_STATE_OPERATING, cpu);
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
2018-04-24 13:18:59 +03:00
|
|
|
run_on_cpu(cs, s390_do_cpu_load_normal, RUN_ON_CPU_NULL);
|
|
|
|
break;
|
|
|
|
default:
|
|
|
|
g_assert_not_reached();
|
|
|
|
}
|
2020-11-14 01:10:22 +03:00
|
|
|
|
|
|
|
CPU_FOREACH(t) {
|
|
|
|
run_on_cpu(t, s390_do_cpu_set_diag318, RUN_ON_CPU_HOST_ULONG(0));
|
|
|
|
}
|
2018-04-24 13:18:59 +03:00
|
|
|
s390_ipl_clear_reset_request();
|
2017-09-13 16:23:58 +03:00
|
|
|
}
|
|
|
|
|
2016-03-04 20:34:33 +03:00
|
|
|
static void s390_machine_device_plug(HotplugHandler *hotplug_dev,
|
|
|
|
DeviceState *dev, Error **errp)
|
|
|
|
{
|
|
|
|
if (object_dynamic_cast(OBJECT(dev), TYPE_CPU)) {
|
|
|
|
s390_cpu_plug(hotplug_dev, dev, errp);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2017-09-13 16:24:12 +03:00
|
|
|
static void s390_machine_device_unplug_request(HotplugHandler *hotplug_dev,
|
|
|
|
DeviceState *dev, Error **errp)
|
|
|
|
{
|
|
|
|
if (object_dynamic_cast(OBJECT(dev), TYPE_CPU)) {
|
|
|
|
error_setg(errp, "CPU hot unplug not supported on this machine");
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2018-02-27 14:02:55 +03:00
|
|
|
static CpuInstanceProperties s390_cpu_index_to_props(MachineState *ms,
|
2017-09-13 16:24:13 +03:00
|
|
|
unsigned cpu_index)
|
|
|
|
{
|
2018-02-27 14:02:55 +03:00
|
|
|
MachineClass *mc = MACHINE_GET_CLASS(ms);
|
|
|
|
const CPUArchIdList *possible_cpus = mc->possible_cpu_arch_ids(ms);
|
2017-09-13 16:24:13 +03:00
|
|
|
|
2018-02-27 14:02:55 +03:00
|
|
|
assert(cpu_index < possible_cpus->len);
|
|
|
|
return possible_cpus->cpus[cpu_index].props;
|
2017-09-13 16:24:13 +03:00
|
|
|
}
|
|
|
|
|
|
|
|
static const CPUArchIdList *s390_possible_cpu_arch_ids(MachineState *ms)
|
|
|
|
{
|
|
|
|
int i;
|
2019-05-18 23:54:24 +03:00
|
|
|
unsigned int max_cpus = ms->smp.max_cpus;
|
2017-09-13 16:24:13 +03:00
|
|
|
|
|
|
|
if (ms->possible_cpus) {
|
|
|
|
g_assert(ms->possible_cpus && ms->possible_cpus->len == max_cpus);
|
|
|
|
return ms->possible_cpus;
|
|
|
|
}
|
|
|
|
|
|
|
|
ms->possible_cpus = g_malloc0(sizeof(CPUArchIdList) +
|
|
|
|
sizeof(CPUArchId) * max_cpus);
|
|
|
|
ms->possible_cpus->len = max_cpus;
|
|
|
|
for (i = 0; i < ms->possible_cpus->len; i++) {
|
2018-01-10 18:22:50 +03:00
|
|
|
ms->possible_cpus->cpus[i].type = ms->cpu_type;
|
2017-09-13 16:24:13 +03:00
|
|
|
ms->possible_cpus->cpus[i].vcpus_count = 1;
|
|
|
|
ms->possible_cpus->cpus[i].arch_id = i;
|
|
|
|
ms->possible_cpus->cpus[i].props.has_core_id = true;
|
|
|
|
ms->possible_cpus->cpus[i].props.core_id = i;
|
|
|
|
}
|
|
|
|
|
|
|
|
return ms->possible_cpus;
|
|
|
|
}
|
|
|
|
|
2016-03-04 20:34:33 +03:00
|
|
|
static HotplugHandler *s390_get_hotplug_handler(MachineState *machine,
|
|
|
|
DeviceState *dev)
|
|
|
|
{
|
|
|
|
if (object_dynamic_cast(OBJECT(dev), TYPE_CPU)) {
|
|
|
|
return HOTPLUG_HANDLER(machine);
|
|
|
|
}
|
|
|
|
return NULL;
|
|
|
|
}
|
|
|
|
|
2017-09-13 16:23:58 +03:00
|
|
|
static void s390_nmi(NMIState *n, int cpu_index, Error **errp)
|
|
|
|
{
|
|
|
|
CPUState *cs = qemu_get_cpu(cpu_index);
|
|
|
|
|
2017-09-28 23:37:06 +03:00
|
|
|
s390_cpu_restart(S390_CPU(cs));
|
2017-09-13 16:23:58 +03:00
|
|
|
}
|
|
|
|
|
2020-04-01 15:37:54 +03:00
|
|
|
static ram_addr_t s390_fixup_ram_size(ram_addr_t sz)
|
|
|
|
{
|
|
|
|
/* same logic as in sclp.c */
|
|
|
|
int increment_size = 20;
|
|
|
|
ram_addr_t newsz;
|
|
|
|
|
|
|
|
while ((sz >> increment_size) > MAX_STORAGE_INCREMENTS) {
|
|
|
|
increment_size++;
|
|
|
|
}
|
|
|
|
newsz = sz >> increment_size << increment_size;
|
|
|
|
|
|
|
|
if (sz != newsz) {
|
|
|
|
qemu_printf("Ram size %" PRIu64 "MB was fixed up to %" PRIu64
|
|
|
|
"MB to match machine restrictions. Consider updating "
|
|
|
|
"the guest definition.\n", (uint64_t) (sz / MiB),
|
|
|
|
(uint64_t) (newsz / MiB));
|
|
|
|
}
|
|
|
|
return newsz;
|
|
|
|
}
|
|
|
|
|
2015-03-12 15:53:51 +03:00
|
|
|
static inline bool machine_get_aes_key_wrap(Object *obj, Error **errp)
|
|
|
|
{
|
|
|
|
S390CcwMachineState *ms = S390_CCW_MACHINE(obj);
|
|
|
|
|
|
|
|
return ms->aes_key_wrap;
|
|
|
|
}
|
|
|
|
|
|
|
|
static inline void machine_set_aes_key_wrap(Object *obj, bool value,
|
|
|
|
Error **errp)
|
|
|
|
{
|
|
|
|
S390CcwMachineState *ms = S390_CCW_MACHINE(obj);
|
|
|
|
|
|
|
|
ms->aes_key_wrap = value;
|
|
|
|
}
|
|
|
|
|
|
|
|
static inline bool machine_get_dea_key_wrap(Object *obj, Error **errp)
|
|
|
|
{
|
|
|
|
S390CcwMachineState *ms = S390_CCW_MACHINE(obj);
|
|
|
|
|
|
|
|
return ms->dea_key_wrap;
|
|
|
|
}
|
|
|
|
|
|
|
|
static inline void machine_set_dea_key_wrap(Object *obj, bool value,
|
|
|
|
Error **errp)
|
|
|
|
{
|
|
|
|
S390CcwMachineState *ms = S390_CCW_MACHINE(obj);
|
|
|
|
|
|
|
|
ms->dea_key_wrap = value;
|
|
|
|
}
|
|
|
|
|
2017-07-11 17:54:36 +03:00
|
|
|
static S390CcwMachineClass *current_mc;
|
2016-03-09 15:11:17 +03:00
|
|
|
|
2020-01-23 20:02:56 +03:00
|
|
|
/*
|
|
|
|
* Get the class of the s390-ccw-virtio machine that is currently in use.
|
|
|
|
* Note: libvirt is using the "none" machine to probe for the features of the
|
|
|
|
* host CPU, so in case this is called with the "none" machine, the function
|
|
|
|
* returns the TYPE_S390_CCW_MACHINE base class. In this base class, all the
|
|
|
|
* various "*_allowed" variables are enabled, so that the *_allowed() wrappers
|
|
|
|
* below return the correct default value for the "none" machine.
|
|
|
|
*
|
|
|
|
* Attention! Do *not* add additional new wrappers for CPU features (e.g. like
|
|
|
|
* the ri_allowed() wrapper) via this mechanism anymore. CPU features should
|
|
|
|
* be handled via the CPU models, i.e. checking with cpu_model_allowed() during
|
|
|
|
* CPU initialization and s390_has_feat() later should be sufficient.
|
|
|
|
*/
|
2017-07-11 17:54:36 +03:00
|
|
|
static S390CcwMachineClass *get_machine_class(void)
|
|
|
|
{
|
|
|
|
if (unlikely(!current_mc)) {
|
2016-09-05 11:52:34 +03:00
|
|
|
/*
|
2017-07-11 17:54:36 +03:00
|
|
|
* No s390 ccw machine was instantiated, we are likely to
|
|
|
|
* be called for the 'none' machine. The properties will
|
|
|
|
* have their after-initialization values.
|
|
|
|
*/
|
2020-08-25 22:20:44 +03:00
|
|
|
current_mc = S390_CCW_MACHINE_CLASS(
|
2017-07-11 17:54:36 +03:00
|
|
|
object_class_by_name(TYPE_S390_CCW_MACHINE));
|
2016-03-09 15:11:17 +03:00
|
|
|
}
|
2017-07-11 17:54:36 +03:00
|
|
|
return current_mc;
|
2016-03-09 15:11:17 +03:00
|
|
|
}
|
|
|
|
|
2017-07-11 17:54:36 +03:00
|
|
|
bool ri_allowed(void)
|
2016-09-07 13:50:40 +03:00
|
|
|
{
|
2017-07-11 17:54:36 +03:00
|
|
|
return get_machine_class()->ri_allowed;
|
|
|
|
}
|
|
|
|
|
|
|
|
bool cpu_model_allowed(void)
|
|
|
|
{
|
|
|
|
return get_machine_class()->cpu_model_allowed;
|
2016-09-07 13:50:40 +03:00
|
|
|
}
|
|
|
|
|
2018-09-28 12:34:35 +03:00
|
|
|
bool hpage_1m_allowed(void)
|
|
|
|
{
|
|
|
|
return get_machine_class()->hpage_1m_allowed;
|
|
|
|
}
|
|
|
|
|
2022-11-03 20:01:40 +03:00
|
|
|
static void machine_get_loadparm(Object *obj, Visitor *v,
|
|
|
|
const char *name, void *opaque,
|
|
|
|
Error **errp)
|
2016-03-29 17:18:47 +03:00
|
|
|
{
|
|
|
|
S390CcwMachineState *ms = S390_CCW_MACHINE(obj);
|
2022-11-03 20:01:40 +03:00
|
|
|
char *str = g_strndup((char *) ms->loadparm, sizeof(ms->loadparm));
|
2016-03-29 17:18:47 +03:00
|
|
|
|
2022-11-03 20:01:40 +03:00
|
|
|
visit_type_str(v, name, &str, errp);
|
|
|
|
g_free(str);
|
2016-03-29 17:18:47 +03:00
|
|
|
}
|
|
|
|
|
2022-11-03 20:01:40 +03:00
|
|
|
static void machine_set_loadparm(Object *obj, Visitor *v,
|
|
|
|
const char *name, void *opaque,
|
|
|
|
Error **errp)
|
2016-03-29 17:18:47 +03:00
|
|
|
{
|
|
|
|
S390CcwMachineState *ms = S390_CCW_MACHINE(obj);
|
2022-11-03 20:01:40 +03:00
|
|
|
char *val;
|
2016-03-29 17:18:47 +03:00
|
|
|
int i;
|
|
|
|
|
2022-11-03 20:01:40 +03:00
|
|
|
if (!visit_type_str(v, name, &val, errp)) {
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
2016-03-29 17:18:47 +03:00
|
|
|
for (i = 0; i < sizeof(ms->loadparm) && val[i]; i++) {
|
2017-07-20 19:31:30 +03:00
|
|
|
uint8_t c = qemu_toupper(val[i]); /* mimic HMC */
|
2016-03-29 17:18:47 +03:00
|
|
|
|
|
|
|
if (('A' <= c && c <= 'Z') || ('0' <= c && c <= '9') || (c == '.') ||
|
|
|
|
(c == ' ')) {
|
|
|
|
ms->loadparm[i] = c;
|
|
|
|
} else {
|
|
|
|
error_setg(errp, "LOADPARM: invalid character '%c' (ASCII 0x%02x)",
|
|
|
|
c, c);
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
for (; i < sizeof(ms->loadparm); i++) {
|
|
|
|
ms->loadparm[i] = ' '; /* pad right with spaces */
|
|
|
|
}
|
|
|
|
}
|
2022-11-03 20:01:40 +03:00
|
|
|
|
|
|
|
static void ccw_machine_class_init(ObjectClass *oc, void *data)
|
2015-03-12 15:53:51 +03:00
|
|
|
{
|
2022-11-03 20:01:40 +03:00
|
|
|
MachineClass *mc = MACHINE_CLASS(oc);
|
|
|
|
NMIClass *nc = NMI_CLASS(oc);
|
|
|
|
HotplugHandlerClass *hc = HOTPLUG_HANDLER_CLASS(oc);
|
|
|
|
S390CcwMachineClass *s390mc = S390_CCW_MACHINE_CLASS(mc);
|
|
|
|
|
|
|
|
s390mc->ri_allowed = true;
|
|
|
|
s390mc->cpu_model_allowed = true;
|
|
|
|
s390mc->css_migration_enabled = true;
|
|
|
|
s390mc->hpage_1m_allowed = true;
|
2022-11-03 20:01:41 +03:00
|
|
|
s390mc->max_threads = 1;
|
2022-11-03 20:01:40 +03:00
|
|
|
mc->init = ccw_init;
|
|
|
|
mc->reset = s390_machine_reset;
|
|
|
|
mc->block_default_type = IF_VIRTIO;
|
|
|
|
mc->no_cdrom = 1;
|
|
|
|
mc->no_floppy = 1;
|
|
|
|
mc->no_parallel = 1;
|
|
|
|
mc->no_sdcard = 1;
|
|
|
|
mc->max_cpus = S390_MAX_CPUS;
|
|
|
|
mc->has_hotpluggable_cpus = true;
|
|
|
|
assert(!mc->get_hotplug_handler);
|
|
|
|
mc->get_hotplug_handler = s390_get_hotplug_handler;
|
|
|
|
mc->cpu_index_to_instance_props = s390_cpu_index_to_props;
|
|
|
|
mc->possible_cpu_arch_ids = s390_possible_cpu_arch_ids;
|
|
|
|
/* it is overridden with 'host' cpu *in kvm_arch_init* */
|
|
|
|
mc->default_cpu_type = S390_CPU_TYPE_NAME("qemu");
|
|
|
|
hc->plug = s390_machine_device_plug;
|
|
|
|
hc->unplug_request = s390_machine_device_unplug_request;
|
|
|
|
nc->nmi_monitor_handler = s390_nmi;
|
|
|
|
mc->default_ram_id = "s390.ram";
|
2023-05-11 15:50:36 +03:00
|
|
|
mc->default_nic = "virtio-net-ccw";
|
2022-11-03 20:01:40 +03:00
|
|
|
|
|
|
|
object_class_property_add_bool(oc, "aes-key-wrap",
|
|
|
|
machine_get_aes_key_wrap,
|
|
|
|
machine_set_aes_key_wrap);
|
|
|
|
object_class_property_set_description(oc, "aes-key-wrap",
|
2020-05-05 18:29:15 +03:00
|
|
|
"enable/disable AES key wrapping using the CPACF wrapping key");
|
2015-03-12 15:53:51 +03:00
|
|
|
|
2022-11-03 20:01:40 +03:00
|
|
|
object_class_property_add_bool(oc, "dea-key-wrap",
|
|
|
|
machine_get_dea_key_wrap,
|
|
|
|
machine_set_dea_key_wrap);
|
|
|
|
object_class_property_set_description(oc, "dea-key-wrap",
|
2020-05-05 18:29:15 +03:00
|
|
|
"enable/disable DEA key wrapping using the CPACF wrapping key");
|
2022-11-03 20:01:40 +03:00
|
|
|
|
|
|
|
object_class_property_add(oc, "loadparm", "loadparm",
|
|
|
|
machine_get_loadparm, machine_set_loadparm,
|
|
|
|
NULL, NULL);
|
|
|
|
object_class_property_set_description(oc, "loadparm",
|
2016-03-29 17:18:47 +03:00
|
|
|
"Up to 8 chars in set of [A-Za-z0-9. ] (lower case chars converted"
|
|
|
|
" to upper case) to pass to machine loader, boot manager,"
|
2020-05-05 18:29:15 +03:00
|
|
|
" and guest kernel");
|
2022-11-03 20:01:40 +03:00
|
|
|
}
|
|
|
|
|
|
|
|
static inline void s390_machine_initfn(Object *obj)
|
|
|
|
{
|
|
|
|
S390CcwMachineState *ms = S390_CCW_MACHINE(obj);
|
|
|
|
|
|
|
|
ms->aes_key_wrap = true;
|
|
|
|
ms->dea_key_wrap = true;
|
2015-03-12 15:53:51 +03:00
|
|
|
}
|
|
|
|
|
2014-08-20 16:16:34 +04:00
|
|
|
static const TypeInfo ccw_machine_info = {
|
|
|
|
.name = TYPE_S390_CCW_MACHINE,
|
|
|
|
.parent = TYPE_MACHINE,
|
2015-07-01 12:16:57 +03:00
|
|
|
.abstract = true,
|
2015-03-12 15:53:51 +03:00
|
|
|
.instance_size = sizeof(S390CcwMachineState),
|
|
|
|
.instance_init = s390_machine_initfn,
|
2016-03-09 15:11:17 +03:00
|
|
|
.class_size = sizeof(S390CcwMachineClass),
|
2014-08-20 16:16:34 +04:00
|
|
|
.class_init = ccw_machine_class_init,
|
2014-08-20 16:16:35 +04:00
|
|
|
.interfaces = (InterfaceInfo[]) {
|
|
|
|
{ TYPE_NMI },
|
2016-03-04 20:34:33 +03:00
|
|
|
{ TYPE_HOTPLUG_HANDLER},
|
2014-08-20 16:16:35 +04:00
|
|
|
{ }
|
|
|
|
},
|
2013-01-24 10:08:56 +04:00
|
|
|
};
|
|
|
|
|
2017-07-11 17:54:37 +03:00
|
|
|
bool css_migration_enabled(void)
|
|
|
|
{
|
|
|
|
return get_machine_class()->css_migration_enabled;
|
|
|
|
}
|
|
|
|
|
2016-03-03 14:48:34 +03:00
|
|
|
#define DEFINE_CCW_MACHINE(suffix, verstr, latest) \
|
|
|
|
static void ccw_machine_##suffix##_class_init(ObjectClass *oc, \
|
|
|
|
void *data) \
|
|
|
|
{ \
|
|
|
|
MachineClass *mc = MACHINE_CLASS(oc); \
|
|
|
|
ccw_machine_##suffix##_class_options(mc); \
|
2022-05-06 09:50:26 +03:00
|
|
|
mc->desc = "Virtual s390x machine (version " verstr ")"; \
|
2016-03-03 14:48:34 +03:00
|
|
|
if (latest) { \
|
|
|
|
mc->alias = "s390-ccw-virtio"; \
|
2020-02-07 19:19:47 +03:00
|
|
|
mc->is_default = true; \
|
2016-03-03 14:48:34 +03:00
|
|
|
} \
|
|
|
|
} \
|
|
|
|
static void ccw_machine_##suffix##_instance_init(Object *obj) \
|
|
|
|
{ \
|
|
|
|
MachineState *machine = MACHINE(obj); \
|
2020-08-25 22:20:44 +03:00
|
|
|
current_mc = S390_CCW_MACHINE_CLASS(MACHINE_GET_CLASS(machine)); \
|
2016-03-03 14:48:34 +03:00
|
|
|
ccw_machine_##suffix##_instance_options(machine); \
|
|
|
|
} \
|
|
|
|
static const TypeInfo ccw_machine_##suffix##_info = { \
|
|
|
|
.name = MACHINE_TYPE_NAME("s390-ccw-virtio-" verstr), \
|
|
|
|
.parent = TYPE_S390_CCW_MACHINE, \
|
|
|
|
.class_init = ccw_machine_##suffix##_class_init, \
|
|
|
|
.instance_init = ccw_machine_##suffix##_instance_init, \
|
|
|
|
}; \
|
|
|
|
static void ccw_machine_register_##suffix(void) \
|
|
|
|
{ \
|
|
|
|
type_register_static(&ccw_machine_##suffix##_info); \
|
|
|
|
} \
|
2016-02-16 23:59:04 +03:00
|
|
|
type_init(ccw_machine_register_##suffix)
|
2016-03-03 14:48:34 +03:00
|
|
|
|
2023-03-14 20:30:09 +03:00
|
|
|
static void ccw_machine_8_1_instance_options(MachineState *machine)
|
|
|
|
{
|
|
|
|
}
|
|
|
|
|
|
|
|
static void ccw_machine_8_1_class_options(MachineClass *mc)
|
|
|
|
{
|
|
|
|
}
|
|
|
|
DEFINE_CCW_MACHINE(8_1, "8.1", true);
|
|
|
|
|
2022-12-12 18:21:44 +03:00
|
|
|
static void ccw_machine_8_0_instance_options(MachineState *machine)
|
|
|
|
{
|
2023-03-14 20:30:09 +03:00
|
|
|
ccw_machine_8_1_instance_options(machine);
|
2022-12-12 18:21:44 +03:00
|
|
|
}
|
|
|
|
|
|
|
|
static void ccw_machine_8_0_class_options(MachineClass *mc)
|
|
|
|
{
|
2023-03-14 20:30:09 +03:00
|
|
|
ccw_machine_8_1_class_options(mc);
|
|
|
|
compat_props_add(mc->compat_props, hw_compat_8_0, hw_compat_8_0_len);
|
2022-12-12 18:21:44 +03:00
|
|
|
}
|
2023-03-14 20:30:09 +03:00
|
|
|
DEFINE_CCW_MACHINE(8_0, "8.0", false);
|
2022-12-12 18:21:44 +03:00
|
|
|
|
2022-07-27 15:17:55 +03:00
|
|
|
static void ccw_machine_7_2_instance_options(MachineState *machine)
|
|
|
|
{
|
2022-12-12 18:21:44 +03:00
|
|
|
ccw_machine_8_0_instance_options(machine);
|
2022-07-27 15:17:55 +03:00
|
|
|
}
|
|
|
|
|
|
|
|
static void ccw_machine_7_2_class_options(MachineClass *mc)
|
|
|
|
{
|
2022-12-12 18:21:44 +03:00
|
|
|
ccw_machine_8_0_class_options(mc);
|
|
|
|
compat_props_add(mc->compat_props, hw_compat_7_2, hw_compat_7_2_len);
|
2022-07-27 15:17:55 +03:00
|
|
|
}
|
2022-12-12 18:21:44 +03:00
|
|
|
DEFINE_CCW_MACHINE(7_2, "7.2", false);
|
2022-07-27 15:17:55 +03:00
|
|
|
|
2022-03-16 17:55:21 +03:00
|
|
|
static void ccw_machine_7_1_instance_options(MachineState *machine)
|
|
|
|
{
|
2022-09-22 18:38:20 +03:00
|
|
|
static const S390FeatInit qemu_cpu_feat = { S390_FEAT_LIST_QEMU_V7_1 };
|
|
|
|
|
2022-07-27 15:17:55 +03:00
|
|
|
ccw_machine_7_2_instance_options(machine);
|
2022-07-27 16:51:20 +03:00
|
|
|
s390_cpudef_featoff_greater(16, 1, S390_FEAT_PAIE);
|
2022-09-22 18:38:20 +03:00
|
|
|
s390_set_qemu_cpu_model(0x8561, 15, 1, qemu_cpu_feat);
|
2022-03-16 17:55:21 +03:00
|
|
|
}
|
|
|
|
|
|
|
|
static void ccw_machine_7_1_class_options(MachineClass *mc)
|
|
|
|
{
|
2022-11-03 20:01:41 +03:00
|
|
|
S390CcwMachineClass *s390mc = S390_CCW_MACHINE_CLASS(mc);
|
2022-11-07 19:13:49 +03:00
|
|
|
static GlobalProperty compat[] = {
|
|
|
|
{ TYPE_S390_PCI_DEVICE, "interpret", "off", },
|
|
|
|
{ TYPE_S390_PCI_DEVICE, "forwarding-assist", "off", },
|
|
|
|
};
|
2022-11-03 20:01:41 +03:00
|
|
|
|
2022-07-27 15:17:55 +03:00
|
|
|
ccw_machine_7_2_class_options(mc);
|
|
|
|
compat_props_add(mc->compat_props, hw_compat_7_1, hw_compat_7_1_len);
|
2022-11-07 19:13:49 +03:00
|
|
|
compat_props_add(mc->compat_props, compat, G_N_ELEMENTS(compat));
|
2022-11-03 20:01:41 +03:00
|
|
|
s390mc->max_threads = S390_MAX_CPUS;
|
2022-03-16 17:55:21 +03:00
|
|
|
}
|
2022-07-27 15:17:55 +03:00
|
|
|
DEFINE_CCW_MACHINE(7_1, "7.1", false);
|
2022-03-16 17:55:21 +03:00
|
|
|
|
2021-12-17 17:39:48 +03:00
|
|
|
static void ccw_machine_7_0_instance_options(MachineState *machine)
|
|
|
|
{
|
2022-04-28 12:47:07 +03:00
|
|
|
static const S390FeatInit qemu_cpu_feat = { S390_FEAT_LIST_QEMU_V7_0 };
|
|
|
|
|
2022-03-16 17:55:21 +03:00
|
|
|
ccw_machine_7_1_instance_options(machine);
|
2022-04-28 12:47:07 +03:00
|
|
|
s390_set_qemu_cpu_model(0x8561, 15, 1, qemu_cpu_feat);
|
2021-12-17 17:39:48 +03:00
|
|
|
}
|
|
|
|
|
|
|
|
static void ccw_machine_7_0_class_options(MachineClass *mc)
|
|
|
|
{
|
2022-03-16 17:55:21 +03:00
|
|
|
ccw_machine_7_1_class_options(mc);
|
|
|
|
compat_props_add(mc->compat_props, hw_compat_7_0, hw_compat_7_0_len);
|
2021-12-17 17:39:48 +03:00
|
|
|
}
|
2022-03-16 17:55:21 +03:00
|
|
|
DEFINE_CCW_MACHINE(7_0, "7.0", false);
|
2021-12-17 17:39:48 +03:00
|
|
|
|
2021-08-31 04:54:26 +03:00
|
|
|
static void ccw_machine_6_2_instance_options(MachineState *machine)
|
|
|
|
{
|
2022-02-24 01:31:15 +03:00
|
|
|
static const S390FeatInit qemu_cpu_feat = { S390_FEAT_LIST_QEMU_V6_2 };
|
|
|
|
|
2021-12-17 17:39:48 +03:00
|
|
|
ccw_machine_7_0_instance_options(machine);
|
2022-02-24 01:31:15 +03:00
|
|
|
s390_set_qemu_cpu_model(0x3906, 14, 2, qemu_cpu_feat);
|
2021-08-31 04:54:26 +03:00
|
|
|
}
|
|
|
|
|
|
|
|
static void ccw_machine_6_2_class_options(MachineClass *mc)
|
|
|
|
{
|
2021-12-17 17:39:48 +03:00
|
|
|
ccw_machine_7_0_class_options(mc);
|
|
|
|
compat_props_add(mc->compat_props, hw_compat_6_2, hw_compat_6_2_len);
|
2021-08-31 04:54:26 +03:00
|
|
|
}
|
2021-12-17 17:39:48 +03:00
|
|
|
DEFINE_CCW_MACHINE(6_2, "6.2", false);
|
2021-08-31 04:54:26 +03:00
|
|
|
|
2021-03-31 14:19:00 +03:00
|
|
|
static void ccw_machine_6_1_instance_options(MachineState *machine)
|
|
|
|
{
|
2021-08-31 04:54:26 +03:00
|
|
|
ccw_machine_6_2_instance_options(machine);
|
2021-09-07 13:10:17 +03:00
|
|
|
s390_cpudef_featoff_greater(16, 1, S390_FEAT_NNPA);
|
|
|
|
s390_cpudef_featoff_greater(16, 1, S390_FEAT_VECTOR_PACKED_DECIMAL_ENH2);
|
|
|
|
s390_cpudef_featoff_greater(16, 1, S390_FEAT_BEAR_ENH);
|
|
|
|
s390_cpudef_featoff_greater(16, 1, S390_FEAT_RDP);
|
|
|
|
s390_cpudef_featoff_greater(16, 1, S390_FEAT_PAI);
|
2021-03-31 14:19:00 +03:00
|
|
|
}
|
|
|
|
|
|
|
|
static void ccw_machine_6_1_class_options(MachineClass *mc)
|
|
|
|
{
|
2021-08-31 04:54:26 +03:00
|
|
|
ccw_machine_6_2_class_options(mc);
|
|
|
|
compat_props_add(mc->compat_props, hw_compat_6_1, hw_compat_6_1_len);
|
2021-09-29 05:58:14 +03:00
|
|
|
mc->smp_props.prefer_sockets = true;
|
2021-03-31 14:19:00 +03:00
|
|
|
}
|
2021-08-31 04:54:26 +03:00
|
|
|
DEFINE_CCW_MACHINE(6_1, "6.1", false);
|
2021-03-31 14:19:00 +03:00
|
|
|
|
2020-11-09 20:39:28 +03:00
|
|
|
static void ccw_machine_6_0_instance_options(MachineState *machine)
|
|
|
|
{
|
2021-06-08 12:23:37 +03:00
|
|
|
static const S390FeatInit qemu_cpu_feat = { S390_FEAT_LIST_QEMU_V6_0 };
|
|
|
|
|
2021-03-31 14:19:00 +03:00
|
|
|
ccw_machine_6_1_instance_options(machine);
|
2021-06-08 12:23:37 +03:00
|
|
|
s390_set_qemu_cpu_model(0x2964, 13, 2, qemu_cpu_feat);
|
2020-11-09 20:39:28 +03:00
|
|
|
}
|
|
|
|
|
|
|
|
static void ccw_machine_6_0_class_options(MachineClass *mc)
|
|
|
|
{
|
2021-03-31 14:19:00 +03:00
|
|
|
ccw_machine_6_1_class_options(mc);
|
|
|
|
compat_props_add(mc->compat_props, hw_compat_6_0, hw_compat_6_0_len);
|
2020-11-09 20:39:28 +03:00
|
|
|
}
|
2021-03-31 14:19:00 +03:00
|
|
|
DEFINE_CCW_MACHINE(6_0, "6.0", false);
|
2020-11-09 20:39:28 +03:00
|
|
|
|
2020-08-19 17:40:16 +03:00
|
|
|
static void ccw_machine_5_2_instance_options(MachineState *machine)
|
|
|
|
{
|
2020-11-09 20:39:28 +03:00
|
|
|
ccw_machine_6_0_instance_options(machine);
|
2020-08-19 17:40:16 +03:00
|
|
|
}
|
|
|
|
|
|
|
|
static void ccw_machine_5_2_class_options(MachineClass *mc)
|
|
|
|
{
|
2020-11-09 20:39:28 +03:00
|
|
|
ccw_machine_6_0_class_options(mc);
|
|
|
|
compat_props_add(mc->compat_props, hw_compat_5_2, hw_compat_5_2_len);
|
2020-08-19 17:40:16 +03:00
|
|
|
}
|
2020-11-09 20:39:28 +03:00
|
|
|
DEFINE_CCW_MACHINE(5_2, "5.2", false);
|
2020-08-19 17:40:16 +03:00
|
|
|
|
2020-04-29 17:46:05 +03:00
|
|
|
static void ccw_machine_5_1_instance_options(MachineState *machine)
|
|
|
|
{
|
2020-08-19 17:40:16 +03:00
|
|
|
ccw_machine_5_2_instance_options(machine);
|
2020-04-29 17:46:05 +03:00
|
|
|
}
|
|
|
|
|
|
|
|
static void ccw_machine_5_1_class_options(MachineClass *mc)
|
|
|
|
{
|
2020-08-19 17:40:16 +03:00
|
|
|
ccw_machine_5_2_class_options(mc);
|
|
|
|
compat_props_add(mc->compat_props, hw_compat_5_1, hw_compat_5_1_len);
|
2020-04-29 17:46:05 +03:00
|
|
|
}
|
2020-08-19 17:40:16 +03:00
|
|
|
DEFINE_CCW_MACHINE(5_1, "5.1", false);
|
2020-04-29 17:46:05 +03:00
|
|
|
|
2019-11-12 13:48:11 +03:00
|
|
|
static void ccw_machine_5_0_instance_options(MachineState *machine)
|
|
|
|
{
|
2020-04-29 17:46:05 +03:00
|
|
|
ccw_machine_5_1_instance_options(machine);
|
2019-11-12 13:48:11 +03:00
|
|
|
}
|
|
|
|
|
|
|
|
static void ccw_machine_5_0_class_options(MachineClass *mc)
|
|
|
|
{
|
2020-04-29 17:46:05 +03:00
|
|
|
ccw_machine_5_1_class_options(mc);
|
|
|
|
compat_props_add(mc->compat_props, hw_compat_5_0, hw_compat_5_0_len);
|
2019-11-12 13:48:11 +03:00
|
|
|
}
|
2020-04-29 17:46:05 +03:00
|
|
|
DEFINE_CCW_MACHINE(5_0, "5.0", false);
|
2019-11-12 13:48:11 +03:00
|
|
|
|
2019-07-24 13:35:24 +03:00
|
|
|
static void ccw_machine_4_2_instance_options(MachineState *machine)
|
|
|
|
{
|
2019-11-12 13:48:11 +03:00
|
|
|
ccw_machine_5_0_instance_options(machine);
|
2019-07-24 13:35:24 +03:00
|
|
|
}
|
|
|
|
|
|
|
|
static void ccw_machine_4_2_class_options(MachineClass *mc)
|
|
|
|
{
|
2019-11-12 13:48:11 +03:00
|
|
|
ccw_machine_5_0_class_options(mc);
|
2020-04-01 15:37:54 +03:00
|
|
|
mc->fixup_ram_size = s390_fixup_ram_size;
|
2019-11-05 21:22:17 +03:00
|
|
|
compat_props_add(mc->compat_props, hw_compat_4_2, hw_compat_4_2_len);
|
2019-07-24 13:35:24 +03:00
|
|
|
}
|
2019-11-12 13:48:11 +03:00
|
|
|
DEFINE_CCW_MACHINE(4_2, "4.2", false);
|
2019-07-24 13:35:24 +03:00
|
|
|
|
2019-04-11 13:20:25 +03:00
|
|
|
static void ccw_machine_4_1_instance_options(MachineState *machine)
|
|
|
|
{
|
2019-08-05 11:13:52 +03:00
|
|
|
static const S390FeatInit qemu_cpu_feat = { S390_FEAT_LIST_QEMU_V4_1 };
|
2019-07-24 13:35:24 +03:00
|
|
|
ccw_machine_4_2_instance_options(machine);
|
2019-08-05 11:13:52 +03:00
|
|
|
s390_set_qemu_cpu_model(0x2964, 13, 2, qemu_cpu_feat);
|
2019-04-11 13:20:25 +03:00
|
|
|
}
|
|
|
|
|
|
|
|
static void ccw_machine_4_1_class_options(MachineClass *mc)
|
|
|
|
{
|
2019-07-24 13:35:24 +03:00
|
|
|
ccw_machine_4_2_class_options(mc);
|
|
|
|
compat_props_add(mc->compat_props, hw_compat_4_1, hw_compat_4_1_len);
|
2019-04-11 13:20:25 +03:00
|
|
|
}
|
2019-07-24 13:35:24 +03:00
|
|
|
DEFINE_CCW_MACHINE(4_1, "4.1", false);
|
2019-04-11 13:20:25 +03:00
|
|
|
|
2018-11-19 13:58:53 +03:00
|
|
|
static void ccw_machine_4_0_instance_options(MachineState *machine)
|
|
|
|
{
|
2019-02-27 11:12:09 +03:00
|
|
|
static const S390FeatInit qemu_cpu_feat = { S390_FEAT_LIST_QEMU_V4_0 };
|
2019-04-11 13:20:25 +03:00
|
|
|
ccw_machine_4_1_instance_options(machine);
|
2019-02-27 11:12:09 +03:00
|
|
|
s390_set_qemu_cpu_model(0x2827, 12, 2, qemu_cpu_feat);
|
2018-11-19 13:58:53 +03:00
|
|
|
}
|
|
|
|
|
|
|
|
static void ccw_machine_4_0_class_options(MachineClass *mc)
|
|
|
|
{
|
2019-04-11 13:20:25 +03:00
|
|
|
ccw_machine_4_1_class_options(mc);
|
|
|
|
compat_props_add(mc->compat_props, hw_compat_4_0, hw_compat_4_0_len);
|
2018-11-19 13:58:53 +03:00
|
|
|
}
|
2019-04-11 13:20:25 +03:00
|
|
|
DEFINE_CCW_MACHINE(4_0, "4.0", false);
|
2018-11-19 13:58:53 +03:00
|
|
|
|
2018-07-23 16:00:54 +03:00
|
|
|
static void ccw_machine_3_1_instance_options(MachineState *machine)
|
|
|
|
{
|
2019-02-12 14:23:23 +03:00
|
|
|
static const S390FeatInit qemu_cpu_feat = { S390_FEAT_LIST_QEMU_V3_1 };
|
2018-11-19 13:58:53 +03:00
|
|
|
ccw_machine_4_0_instance_options(machine);
|
2019-02-12 04:16:56 +03:00
|
|
|
s390_cpudef_featoff_greater(14, 1, S390_FEAT_MULTIPLE_EPOCH);
|
|
|
|
s390_cpudef_group_featoff_greater(14, 1, S390_FEAT_GROUP_MULTIPLE_EPOCH_PTFF);
|
2019-02-12 14:23:23 +03:00
|
|
|
s390_set_qemu_cpu_model(0x2827, 12, 2, qemu_cpu_feat);
|
2018-07-23 16:00:54 +03:00
|
|
|
}
|
|
|
|
|
|
|
|
static void ccw_machine_3_1_class_options(MachineClass *mc)
|
|
|
|
{
|
2018-11-19 13:58:53 +03:00
|
|
|
ccw_machine_4_0_class_options(mc);
|
2018-12-12 18:36:30 +03:00
|
|
|
compat_props_add(mc->compat_props, hw_compat_3_1, hw_compat_3_1_len);
|
2018-07-23 16:00:54 +03:00
|
|
|
}
|
2018-11-19 13:58:53 +03:00
|
|
|
DEFINE_CCW_MACHINE(3_1, "3.1", false);
|
2018-07-23 16:00:54 +03:00
|
|
|
|
2018-05-22 13:39:58 +03:00
|
|
|
static void ccw_machine_3_0_instance_options(MachineState *machine)
|
2018-03-29 14:22:56 +03:00
|
|
|
{
|
2018-07-23 16:00:54 +03:00
|
|
|
ccw_machine_3_1_instance_options(machine);
|
2018-03-29 14:22:56 +03:00
|
|
|
}
|
|
|
|
|
2018-05-22 13:39:58 +03:00
|
|
|
static void ccw_machine_3_0_class_options(MachineClass *mc)
|
2018-03-29 14:22:56 +03:00
|
|
|
{
|
2020-08-25 22:20:44 +03:00
|
|
|
S390CcwMachineClass *s390mc = S390_CCW_MACHINE_CLASS(mc);
|
2018-09-28 12:34:35 +03:00
|
|
|
|
|
|
|
s390mc->hpage_1m_allowed = false;
|
2018-07-23 16:00:54 +03:00
|
|
|
ccw_machine_3_1_class_options(mc);
|
2018-12-12 18:36:30 +03:00
|
|
|
compat_props_add(mc->compat_props, hw_compat_3_0, hw_compat_3_0_len);
|
2018-03-29 14:22:56 +03:00
|
|
|
}
|
2018-07-23 16:00:54 +03:00
|
|
|
DEFINE_CCW_MACHINE(3_0, "3.0", false);
|
2018-03-29 14:22:56 +03:00
|
|
|
|
2017-11-24 18:26:51 +03:00
|
|
|
static void ccw_machine_2_12_instance_options(MachineState *machine)
|
|
|
|
{
|
2018-05-22 13:39:58 +03:00
|
|
|
ccw_machine_3_0_instance_options(machine);
|
2018-06-26 15:38:30 +03:00
|
|
|
s390_cpudef_featoff_greater(11, 1, S390_FEAT_PPA15);
|
|
|
|
s390_cpudef_featoff_greater(11, 1, S390_FEAT_BPB);
|
2017-11-24 18:26:51 +03:00
|
|
|
}
|
|
|
|
|
|
|
|
static void ccw_machine_2_12_class_options(MachineClass *mc)
|
|
|
|
{
|
2018-05-22 13:39:58 +03:00
|
|
|
ccw_machine_3_0_class_options(mc);
|
2018-12-12 18:36:30 +03:00
|
|
|
compat_props_add(mc->compat_props, hw_compat_2_12, hw_compat_2_12_len);
|
2017-11-24 18:26:51 +03:00
|
|
|
}
|
2018-03-29 14:22:56 +03:00
|
|
|
DEFINE_CCW_MACHINE(2_12, "2.12", false);
|
2017-11-24 18:26:51 +03:00
|
|
|
|
2017-08-10 15:07:31 +03:00
|
|
|
static void ccw_machine_2_11_instance_options(MachineState *machine)
|
|
|
|
{
|
2017-12-08 19:55:29 +03:00
|
|
|
static const S390FeatInit qemu_cpu_feat = { S390_FEAT_LIST_QEMU_V2_11 };
|
2017-11-24 18:26:51 +03:00
|
|
|
ccw_machine_2_12_instance_options(machine);
|
2017-12-08 19:55:29 +03:00
|
|
|
|
|
|
|
/* before 2.12 we emulated the very first z900 */
|
|
|
|
s390_set_qemu_cpu_model(0x2064, 7, 1, qemu_cpu_feat);
|
2017-08-10 15:07:31 +03:00
|
|
|
}
|
|
|
|
|
|
|
|
static void ccw_machine_2_11_class_options(MachineClass *mc)
|
|
|
|
{
|
2018-12-12 17:01:23 +03:00
|
|
|
static GlobalProperty compat[] = {
|
2019-01-07 22:30:20 +03:00
|
|
|
{ TYPE_SCLP_EVENT_FACILITY, "allow_all_mask_sizes", "off", },
|
2018-12-12 17:01:23 +03:00
|
|
|
};
|
|
|
|
|
2017-11-24 18:26:51 +03:00
|
|
|
ccw_machine_2_12_class_options(mc);
|
2018-12-12 18:36:30 +03:00
|
|
|
compat_props_add(mc->compat_props, hw_compat_2_11, hw_compat_2_11_len);
|
2018-12-12 17:01:23 +03:00
|
|
|
compat_props_add(mc->compat_props, compat, G_N_ELEMENTS(compat));
|
2017-08-10 15:07:31 +03:00
|
|
|
}
|
2017-11-24 18:26:51 +03:00
|
|
|
DEFINE_CCW_MACHINE(2_11, "2.11", false);
|
2017-08-10 15:07:31 +03:00
|
|
|
|
2017-04-03 18:41:33 +03:00
|
|
|
static void ccw_machine_2_10_instance_options(MachineState *machine)
|
|
|
|
{
|
2017-08-10 15:07:31 +03:00
|
|
|
ccw_machine_2_11_instance_options(machine);
|
2017-04-03 18:41:33 +03:00
|
|
|
}
|
|
|
|
|
|
|
|
static void ccw_machine_2_10_class_options(MachineClass *mc)
|
|
|
|
{
|
2017-08-10 15:07:31 +03:00
|
|
|
ccw_machine_2_11_class_options(mc);
|
2018-12-12 18:36:30 +03:00
|
|
|
compat_props_add(mc->compat_props, hw_compat_2_10, hw_compat_2_10_len);
|
2017-04-03 18:41:33 +03:00
|
|
|
}
|
2017-08-10 15:07:31 +03:00
|
|
|
DEFINE_CCW_MACHINE(2_10, "2.10", false);
|
2017-04-03 18:41:33 +03:00
|
|
|
|
2016-11-30 17:52:46 +03:00
|
|
|
static void ccw_machine_2_9_instance_options(MachineState *machine)
|
|
|
|
{
|
2017-04-03 18:41:33 +03:00
|
|
|
ccw_machine_2_10_instance_options(machine);
|
2017-04-10 16:39:00 +03:00
|
|
|
s390_cpudef_featoff_greater(12, 1, S390_FEAT_ESOP);
|
|
|
|
s390_cpudef_featoff_greater(12, 1, S390_FEAT_SIDE_EFFECT_ACCESS_ESOP2);
|
2017-06-14 08:25:58 +03:00
|
|
|
s390_cpudef_featoff_greater(12, 1, S390_FEAT_ZPCI);
|
|
|
|
s390_cpudef_featoff_greater(12, 1, S390_FEAT_ADAPTER_INT_SUPPRESSION);
|
|
|
|
s390_cpudef_featoff_greater(12, 1, S390_FEAT_ADAPTER_EVENT_NOTIFICATION);
|
2016-11-30 17:52:46 +03:00
|
|
|
}
|
|
|
|
|
|
|
|
static void ccw_machine_2_9_class_options(MachineClass *mc)
|
|
|
|
{
|
2020-08-25 22:20:44 +03:00
|
|
|
S390CcwMachineClass *s390mc = S390_CCW_MACHINE_CLASS(mc);
|
2018-12-12 17:01:23 +03:00
|
|
|
static GlobalProperty compat[] = {
|
2019-01-07 22:30:20 +03:00
|
|
|
{ TYPE_S390_STATTRIB, "migration-enabled", "off", },
|
2018-12-12 17:01:23 +03:00
|
|
|
};
|
2017-07-11 17:54:37 +03:00
|
|
|
|
2017-04-03 18:41:33 +03:00
|
|
|
ccw_machine_2_10_class_options(mc);
|
2018-12-12 18:36:30 +03:00
|
|
|
compat_props_add(mc->compat_props, hw_compat_2_9, hw_compat_2_9_len);
|
2018-12-12 17:01:23 +03:00
|
|
|
compat_props_add(mc->compat_props, compat, G_N_ELEMENTS(compat));
|
2017-07-11 17:54:37 +03:00
|
|
|
s390mc->css_migration_enabled = false;
|
2016-11-30 17:52:46 +03:00
|
|
|
}
|
2017-04-03 18:41:33 +03:00
|
|
|
DEFINE_CCW_MACHINE(2_9, "2.9", false);
|
2016-11-30 17:52:46 +03:00
|
|
|
|
2016-08-12 10:26:52 +03:00
|
|
|
static void ccw_machine_2_8_instance_options(MachineState *machine)
|
|
|
|
{
|
2016-11-30 17:52:46 +03:00
|
|
|
ccw_machine_2_9_instance_options(machine);
|
2016-08-12 10:26:52 +03:00
|
|
|
}
|
|
|
|
|
|
|
|
static void ccw_machine_2_8_class_options(MachineClass *mc)
|
|
|
|
{
|
2018-12-12 17:01:23 +03:00
|
|
|
static GlobalProperty compat[] = {
|
2019-01-07 22:30:20 +03:00
|
|
|
{ TYPE_S390_FLIC_COMMON, "adapter_routes_max_batch", "64", },
|
2018-12-12 17:01:23 +03:00
|
|
|
};
|
|
|
|
|
2016-11-30 17:52:46 +03:00
|
|
|
ccw_machine_2_9_class_options(mc);
|
2018-12-12 18:36:30 +03:00
|
|
|
compat_props_add(mc->compat_props, hw_compat_2_8, hw_compat_2_8_len);
|
2018-12-12 17:01:23 +03:00
|
|
|
compat_props_add(mc->compat_props, compat, G_N_ELEMENTS(compat));
|
2016-08-12 10:26:52 +03:00
|
|
|
}
|
2016-11-30 17:52:46 +03:00
|
|
|
DEFINE_CCW_MACHINE(2_8, "2.8", false);
|
2016-08-12 10:26:52 +03:00
|
|
|
|
2016-04-25 11:37:23 +03:00
|
|
|
static void ccw_machine_2_7_instance_options(MachineState *machine)
|
|
|
|
{
|
2016-08-12 10:26:52 +03:00
|
|
|
ccw_machine_2_8_instance_options(machine);
|
2016-04-25 11:37:23 +03:00
|
|
|
}
|
|
|
|
|
|
|
|
static void ccw_machine_2_7_class_options(MachineClass *mc)
|
|
|
|
{
|
2020-08-25 22:20:44 +03:00
|
|
|
S390CcwMachineClass *s390mc = S390_CCW_MACHINE_CLASS(mc);
|
2016-09-07 13:50:40 +03:00
|
|
|
|
|
|
|
s390mc->cpu_model_allowed = false;
|
2016-08-12 10:26:52 +03:00
|
|
|
ccw_machine_2_8_class_options(mc);
|
2018-12-12 18:36:30 +03:00
|
|
|
compat_props_add(mc->compat_props, hw_compat_2_7, hw_compat_2_7_len);
|
2016-04-25 11:37:23 +03:00
|
|
|
}
|
2016-08-12 10:26:52 +03:00
|
|
|
DEFINE_CCW_MACHINE(2_7, "2.7", false);
|
2016-04-25 11:37:23 +03:00
|
|
|
|
2016-03-03 14:48:34 +03:00
|
|
|
static void ccw_machine_2_6_instance_options(MachineState *machine)
|
2015-07-01 12:16:57 +03:00
|
|
|
{
|
2016-04-25 11:37:23 +03:00
|
|
|
ccw_machine_2_7_instance_options(machine);
|
2015-07-01 12:16:57 +03:00
|
|
|
}
|
|
|
|
|
2016-03-03 14:48:34 +03:00
|
|
|
static void ccw_machine_2_6_class_options(MachineClass *mc)
|
2015-07-17 14:16:52 +03:00
|
|
|
{
|
2020-08-25 22:20:44 +03:00
|
|
|
S390CcwMachineClass *s390mc = S390_CCW_MACHINE_CLASS(mc);
|
2018-12-12 17:01:23 +03:00
|
|
|
static GlobalProperty compat[] = {
|
2019-01-07 22:30:20 +03:00
|
|
|
{ TYPE_S390_IPL, "iplbext_migration", "off", },
|
|
|
|
{ TYPE_VIRTUAL_CSS_BRIDGE, "css_dev_path", "off", },
|
2018-12-12 17:01:23 +03:00
|
|
|
};
|
2016-03-09 15:11:17 +03:00
|
|
|
|
|
|
|
s390mc->ri_allowed = false;
|
2016-04-25 11:37:23 +03:00
|
|
|
ccw_machine_2_7_class_options(mc);
|
2018-12-12 18:36:30 +03:00
|
|
|
compat_props_add(mc->compat_props, hw_compat_2_6, hw_compat_2_6_len);
|
2018-12-12 17:01:23 +03:00
|
|
|
compat_props_add(mc->compat_props, compat, G_N_ELEMENTS(compat));
|
2015-07-17 14:16:52 +03:00
|
|
|
}
|
2016-04-25 11:37:23 +03:00
|
|
|
DEFINE_CCW_MACHINE(2_6, "2.6", false);
|
2015-07-17 14:16:52 +03:00
|
|
|
|
2016-03-03 14:48:34 +03:00
|
|
|
static void ccw_machine_2_5_instance_options(MachineState *machine)
|
|
|
|
{
|
2016-04-25 11:37:23 +03:00
|
|
|
ccw_machine_2_6_instance_options(machine);
|
2016-03-03 14:48:34 +03:00
|
|
|
}
|
2015-07-17 14:16:52 +03:00
|
|
|
|
2016-03-03 14:48:34 +03:00
|
|
|
static void ccw_machine_2_5_class_options(MachineClass *mc)
|
2015-11-30 12:45:41 +03:00
|
|
|
{
|
2016-04-25 11:37:23 +03:00
|
|
|
ccw_machine_2_6_class_options(mc);
|
2018-12-12 18:36:30 +03:00
|
|
|
compat_props_add(mc->compat_props, hw_compat_2_5, hw_compat_2_5_len);
|
2016-03-03 14:48:34 +03:00
|
|
|
}
|
|
|
|
DEFINE_CCW_MACHINE(2_5, "2.5", false);
|
2015-11-30 12:45:41 +03:00
|
|
|
|
2016-03-03 14:48:34 +03:00
|
|
|
static void ccw_machine_2_4_instance_options(MachineState *machine)
|
|
|
|
{
|
|
|
|
ccw_machine_2_5_instance_options(machine);
|
2015-11-30 12:45:41 +03:00
|
|
|
}
|
|
|
|
|
2016-03-03 14:48:34 +03:00
|
|
|
static void ccw_machine_2_4_class_options(MachineClass *mc)
|
|
|
|
{
|
2018-12-12 17:01:23 +03:00
|
|
|
static GlobalProperty compat[] = {
|
2019-01-07 22:30:20 +03:00
|
|
|
{ TYPE_S390_SKEYS, "migration-enabled", "off", },
|
|
|
|
{ "virtio-blk-ccw", "max_revision", "0", },
|
|
|
|
{ "virtio-balloon-ccw", "max_revision", "0", },
|
|
|
|
{ "virtio-serial-ccw", "max_revision", "0", },
|
|
|
|
{ "virtio-9p-ccw", "max_revision", "0", },
|
|
|
|
{ "virtio-rng-ccw", "max_revision", "0", },
|
|
|
|
{ "virtio-net-ccw", "max_revision", "0", },
|
|
|
|
{ "virtio-scsi-ccw", "max_revision", "0", },
|
|
|
|
{ "vhost-scsi-ccw", "max_revision", "0", },
|
2018-12-12 17:01:23 +03:00
|
|
|
};
|
|
|
|
|
2016-04-25 11:37:23 +03:00
|
|
|
ccw_machine_2_5_class_options(mc);
|
2018-12-12 18:36:30 +03:00
|
|
|
compat_props_add(mc->compat_props, hw_compat_2_4, hw_compat_2_4_len);
|
2018-12-12 17:01:23 +03:00
|
|
|
compat_props_add(mc->compat_props, compat, G_N_ELEMENTS(compat));
|
2016-03-03 14:48:34 +03:00
|
|
|
}
|
|
|
|
DEFINE_CCW_MACHINE(2_4, "2.4", false);
|
2015-11-30 12:45:41 +03:00
|
|
|
|
2014-08-20 16:16:34 +04:00
|
|
|
static void ccw_machine_register_types(void)
|
2013-01-24 10:08:56 +04:00
|
|
|
{
|
2014-08-20 16:16:34 +04:00
|
|
|
type_register_static(&ccw_machine_info);
|
2013-01-24 10:08:56 +04:00
|
|
|
}
|
|
|
|
|
2014-08-20 16:16:34 +04:00
|
|
|
type_init(ccw_machine_register_types)
|