2013-01-24 10:08:56 +04:00
|
|
|
/*
|
|
|
|
* virtio ccw machine
|
|
|
|
*
|
|
|
|
* Copyright 2012 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>
|
|
|
|
*
|
|
|
|
* 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"
|
2016-01-19 23:51:44 +03:00
|
|
|
#include "cpu.h"
|
2013-01-24 10:08:56 +04:00
|
|
|
#include "hw/boards.h"
|
|
|
|
#include "exec/address-spaces.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"
|
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"
|
2015-01-09 11:04:38 +03:00
|
|
|
#include "s390-pci-bus.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-10-16 13:25:52 +03:00
|
|
|
#include "hw/compat.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"
|
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"
|
|
|
|
|
|
|
|
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));
|
|
|
|
Error *err = NULL;
|
|
|
|
|
|
|
|
object_property_set_int(OBJECT(cpu), core_id, "core-id", &err);
|
|
|
|
if (err != NULL) {
|
|
|
|
goto out;
|
|
|
|
}
|
|
|
|
object_property_set_bool(OBJECT(cpu), true, "realized", &err);
|
|
|
|
|
|
|
|
out:
|
|
|
|
object_unref(OBJECT(cpu));
|
|
|
|
if (err) {
|
|
|
|
error_propagate(errp, err);
|
|
|
|
cpu = NULL;
|
|
|
|
}
|
|
|
|
return cpu;
|
|
|
|
}
|
|
|
|
|
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);
|
2017-09-13 16:23:58 +03:00
|
|
|
int i;
|
|
|
|
|
2017-09-13 16:24:13 +03:00
|
|
|
/* initialize possible_cpus */
|
|
|
|
mc->possible_cpu_arch_ids(machine);
|
|
|
|
|
2017-09-13 16:23:58 +03:00
|
|
|
for (i = 0; i < 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",
|
|
|
|
};
|
|
|
|
|
2015-10-01 11:49:47 +03:00
|
|
|
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) {
|
|
|
|
qdev_reset_all(dev);
|
|
|
|
}
|
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];
|
|
|
|
|
|
|
|
if (mem < ram_size) {
|
|
|
|
/* 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);
|
|
|
|
}
|
|
|
|
|
2017-12-11 15:21:46 +03:00
|
|
|
/*
|
|
|
|
* KVM does only support memory slots up to KVM_MEM_MAX_NR_PAGES pages
|
|
|
|
* as the dirty bitmap must be managed by bitops that take an int as
|
|
|
|
* position indicator. If we have a guest beyond that we will split off
|
|
|
|
* new subregions. The split must happen on a segment boundary (1MB).
|
|
|
|
*/
|
|
|
|
#define KVM_MEM_MAX_NR_PAGES ((1ULL << 31) - 1)
|
|
|
|
#define SEG_MSK (~0xfffffULL)
|
|
|
|
#define KVM_SLOT_MAX_BYTES ((KVM_MEM_MAX_NR_PAGES * TARGET_PAGE_SIZE) & SEG_MSK)
|
2017-09-13 16:23:58 +03:00
|
|
|
static void s390_memory_init(ram_addr_t mem_size)
|
2013-01-24 10:08:56 +04:00
|
|
|
{
|
|
|
|
MemoryRegion *sysmem = get_system_memory();
|
2017-12-11 15:21:46 +03:00
|
|
|
ram_addr_t chunk, offset = 0;
|
|
|
|
unsigned int number = 0;
|
|
|
|
gchar *name;
|
2015-05-29 16:01:55 +03:00
|
|
|
|
|
|
|
/* allocate RAM for core */
|
2017-12-11 15:21:46 +03:00
|
|
|
name = g_strdup_printf("s390.ram");
|
|
|
|
while (mem_size) {
|
|
|
|
MemoryRegion *ram = g_new(MemoryRegion, 1);
|
|
|
|
uint64_t size = mem_size;
|
|
|
|
|
|
|
|
/* KVM does not allow memslots >= 8 TB */
|
|
|
|
chunk = MIN(size, KVM_SLOT_MAX_BYTES);
|
|
|
|
memory_region_allocate_system_memory(ram, NULL, name, chunk);
|
|
|
|
memory_region_add_subregion(sysmem, offset, ram);
|
|
|
|
mem_size -= chunk;
|
|
|
|
offset += chunk;
|
|
|
|
g_free(name);
|
|
|
|
name = g_strdup_printf("s390.ram.%u", ++number);
|
|
|
|
}
|
|
|
|
g_free(name);
|
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
|
|
|
#define S390_TOD_CLOCK_VALUE_MISSING 0x00
|
|
|
|
#define S390_TOD_CLOCK_VALUE_PRESENT 0x01
|
|
|
|
|
|
|
|
static void gtod_save(QEMUFile *f, void *opaque)
|
|
|
|
{
|
|
|
|
uint64_t tod_low;
|
|
|
|
uint8_t tod_high;
|
|
|
|
int r;
|
|
|
|
|
|
|
|
r = s390_get_clock(&tod_high, &tod_low);
|
|
|
|
if (r) {
|
|
|
|
warn_report("Unable to get guest clock for migration: %s",
|
|
|
|
strerror(-r));
|
|
|
|
error_printf("Guest clock will not be migrated "
|
|
|
|
"which could cause the guest to hang.");
|
|
|
|
qemu_put_byte(f, S390_TOD_CLOCK_VALUE_MISSING);
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
qemu_put_byte(f, S390_TOD_CLOCK_VALUE_PRESENT);
|
|
|
|
qemu_put_byte(f, tod_high);
|
|
|
|
qemu_put_be64(f, tod_low);
|
|
|
|
}
|
|
|
|
|
|
|
|
static int gtod_load(QEMUFile *f, void *opaque, int version_id)
|
|
|
|
{
|
|
|
|
uint64_t tod_low;
|
|
|
|
uint8_t tod_high;
|
|
|
|
int r;
|
|
|
|
|
|
|
|
if (qemu_get_byte(f) == S390_TOD_CLOCK_VALUE_MISSING) {
|
|
|
|
warn_report("Guest clock was not migrated. This could "
|
|
|
|
"cause the guest to hang.");
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
tod_high = qemu_get_byte(f);
|
|
|
|
tod_low = qemu_get_be64(f);
|
|
|
|
|
|
|
|
r = s390_set_clock(&tod_high, &tod_low);
|
|
|
|
if (r) {
|
2017-10-04 13:57:51 +03:00
|
|
|
error_report("Unable to set KVM guest TOD clock: %s", strerror(-r));
|
2017-09-13 16:23:58 +03:00
|
|
|
}
|
|
|
|
|
2017-10-04 13:57:51 +03:00
|
|
|
return r;
|
2017-09-13 16:23:58 +03:00
|
|
|
}
|
|
|
|
|
2017-05-24 15:10:48 +03:00
|
|
|
static SaveVMHandlers savevm_gtod = {
|
|
|
|
.save_state = gtod_save,
|
|
|
|
.load_state = gtod_load,
|
|
|
|
};
|
|
|
|
|
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,
|
|
|
|
new, NULL);
|
|
|
|
object_unref(new);
|
|
|
|
qdev_init_nofail(dev);
|
|
|
|
}
|
|
|
|
|
|
|
|
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");
|
|
|
|
|
|
|
|
dev = qdev_create(bus, name);
|
|
|
|
qdev_set_nic_properties(dev, nd);
|
|
|
|
qdev_init_nofail(dev);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2015-05-29 16:01:55 +03:00
|
|
|
static void ccw_init(MachineState *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();
|
2015-05-29 16:01:55 +03:00
|
|
|
s390_memory_init(machine->ram_size);
|
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);
|
|
|
|
|
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();
|
|
|
|
|
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,
|
2016-10-21 19:17:08 +03:00
|
|
|
machine->initrd_filename, "s390-ccw.img",
|
|
|
|
"s390-netboot.img", true);
|
2013-01-24 10:08:56 +04:00
|
|
|
|
2017-09-28 16:18:31 +03:00
|
|
|
/*
|
|
|
|
* We cannot easily make the pci host bridge conditional as older QEMUs
|
|
|
|
* always created it. Doing so would break migration across QEMU versions.
|
|
|
|
*/
|
|
|
|
dev = qdev_create(NULL, TYPE_S390_PCI_HOST_BRIDGE);
|
|
|
|
object_property_add_child(qdev_get_machine(), TYPE_S390_PCI_HOST_BRIDGE,
|
|
|
|
OBJECT(dev), NULL);
|
|
|
|
qdev_init_nofail(dev);
|
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));
|
2013-01-24 10:08:56 +04:00
|
|
|
/*
|
2017-05-17 03:48:05 +03:00
|
|
|
* Non mcss-e enabled guests only see the devices from the default
|
|
|
|
* css, which is determined by the value of the squash_mcss property.
|
2013-01-24 10:08:56 +04:00
|
|
|
*/
|
2017-05-17 03:48:05 +03:00
|
|
|
if (css_bus->squash_mcss) {
|
|
|
|
ret = css_create_css_image(0, true);
|
|
|
|
} else {
|
|
|
|
ret = css_create_css_image(VIRTUAL_CSSID, true);
|
|
|
|
}
|
2017-12-06 17:44:38 +03:00
|
|
|
if (qemu_opt_get(qemu_get_machine_opts(), "s390-squash-mcss")) {
|
|
|
|
warn_report("The machine property 's390-squash-mcss' is deprecated"
|
|
|
|
" (obsoleted by lifting the cssid restrictions).");
|
|
|
|
}
|
|
|
|
|
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 */
|
|
|
|
s390_create_virtio_net(BUS(css_bus), "virtio-net-ccw");
|
2015-03-09 17:56:08 +03:00
|
|
|
|
|
|
|
/* Register savevm handler for guest TOD clock */
|
2017-08-18 14:43:40 +03:00
|
|
|
register_savevm_live(NULL, "todclock", 0, 1, &savevm_gtod, NULL);
|
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
|
|
|
}
|
|
|
|
|
2017-09-13 16:23:58 +03:00
|
|
|
static void s390_machine_reset(void)
|
|
|
|
{
|
|
|
|
S390CPU *ipl_cpu = S390_CPU(qemu_get_cpu(0));
|
|
|
|
|
|
|
|
s390_cmma_reset();
|
|
|
|
qemu_devices_reset();
|
|
|
|
s390_crypto_reset();
|
|
|
|
|
|
|
|
/* all cpus are stopped - configure and start the ipl cpu only */
|
|
|
|
s390_ipl_prepare_cpu(ipl_cpu);
|
qmp: expose s390-specific CPU info
Presently s390x is the only architecture not exposing specific
CPU information via QMP query-cpus. Upstream discussion has shown
that it could make sense to report the architecture specific CPU
state, e.g. to detect that a CPU has been stopped.
With this change the output of query-cpus will look like this on
s390:
[
{"arch": "s390", "current": true,
"props": {"core-id": 0}, "cpu-state": "operating", "CPU": 0,
"qom_path": "/machine/unattached/device[0]",
"halted": false, "thread_id": 63115},
{"arch": "s390", "current": false,
"props": {"core-id": 1}, "cpu-state": "stopped", "CPU": 1,
"qom_path": "/machine/unattached/device[1]",
"halted": true, "thread_id": 63116}
]
This change doesn't add the s390-specific data to HMP 'info cpus'.
A follow-on patch will remove all architecture specific information
from there.
Signed-off-by: Viktor Mihajlovski <mihajlov@linux.vnet.ibm.com>
Reviewed-by: David Hildenbrand <david@redhat.com>
Reviewed-by: Christian Borntraeger <borntraeger@de.ibm.com>
Reviewed-by: Eric Blake <eblake@redhat.com>
Message-Id: <1518797321-28356-2-git-send-email-mihajlov@linux.vnet.ibm.com>
Reviewed-by: Cornelia Huck <cohuck@redhat.com>
Signed-off-by: Cornelia Huck <cohuck@redhat.com>
2018-02-16 19:08:37 +03:00
|
|
|
s390_cpu_set_state(S390_CPU_STATE_OPERATING, ipl_cpu);
|
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;
|
|
|
|
|
|
|
|
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;
|
|
|
|
}
|
|
|
|
|
2016-03-04 20:34:35 +03:00
|
|
|
static void s390_hot_add_cpu(const int64_t id, Error **errp)
|
|
|
|
{
|
|
|
|
MachineState *machine = MACHINE(qdev_get_machine());
|
2017-09-13 16:24:15 +03:00
|
|
|
ObjectClass *oc;
|
|
|
|
|
|
|
|
g_assert(machine->possible_cpus->cpus[0].cpu);
|
|
|
|
oc = OBJECT_CLASS(CPU_GET_CLASS(machine->possible_cpus->cpus[0].cpu));
|
2016-03-04 20:34:35 +03:00
|
|
|
|
2017-09-13 16:24:15 +03:00
|
|
|
s390x_new_cpu(object_class_get_name(oc), id, errp);
|
2016-03-04 20:34:35 +03:00
|
|
|
}
|
|
|
|
|
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
|
|
|
}
|
|
|
|
|
2014-08-20 16:16:34 +04:00
|
|
|
static void ccw_machine_class_init(ObjectClass *oc, void *data)
|
|
|
|
{
|
|
|
|
MachineClass *mc = MACHINE_CLASS(oc);
|
2014-08-20 16:16:35 +04:00
|
|
|
NMIClass *nc = NMI_CLASS(oc);
|
2016-03-04 20:34:33 +03:00
|
|
|
HotplugHandlerClass *hc = HOTPLUG_HANDLER_CLASS(oc);
|
2016-03-09 15:11:17 +03:00
|
|
|
S390CcwMachineClass *s390mc = S390_MACHINE_CLASS(mc);
|
2014-08-20 16:16:34 +04:00
|
|
|
|
2016-03-09 15:11:17 +03:00
|
|
|
s390mc->ri_allowed = true;
|
2016-09-07 13:50:40 +03:00
|
|
|
s390mc->cpu_model_allowed = true;
|
2017-07-11 17:54:40 +03:00
|
|
|
s390mc->css_migration_enabled = true;
|
2014-08-20 16:16:34 +04:00
|
|
|
mc->init = ccw_init;
|
2015-07-21 14:47:32 +03:00
|
|
|
mc->reset = s390_machine_reset;
|
2016-03-04 20:34:35 +03:00
|
|
|
mc->hot_add_cpu = s390_hot_add_cpu;
|
2014-08-20 16:16:34 +04:00
|
|
|
mc->block_default_type = IF_VIRTIO;
|
|
|
|
mc->no_cdrom = 1;
|
|
|
|
mc->no_floppy = 1;
|
|
|
|
mc->no_serial = 1;
|
|
|
|
mc->no_parallel = 1;
|
|
|
|
mc->no_sdcard = 1;
|
2014-12-03 17:38:28 +03:00
|
|
|
mc->use_sclp = 1;
|
2017-09-28 16:46:09 +03:00
|
|
|
mc->max_cpus = S390_MAX_CPUS;
|
2017-09-13 16:24:13 +03:00
|
|
|
mc->has_hotpluggable_cpus = true;
|
2016-03-04 20:34:33 +03:00
|
|
|
mc->get_hotplug_handler = s390_get_hotplug_handler;
|
2017-09-13 16:24:13 +03:00
|
|
|
mc->cpu_index_to_instance_props = s390_cpu_index_to_props;
|
|
|
|
mc->possible_cpu_arch_ids = s390_possible_cpu_arch_ids;
|
2017-09-21 15:59:08 +03:00
|
|
|
/* it is overridden with 'host' cpu *in kvm_arch_init* */
|
|
|
|
mc->default_cpu_type = S390_CPU_TYPE_NAME("qemu");
|
2016-03-04 20:34:33 +03:00
|
|
|
hc->plug = s390_machine_device_plug;
|
2017-09-13 16:24:12 +03:00
|
|
|
hc->unplug_request = s390_machine_device_unplug_request;
|
2014-08-20 16:16:35 +04:00
|
|
|
nc->nmi_monitor_handler = s390_nmi;
|
2014-08-20 16:16:34 +04:00
|
|
|
}
|
|
|
|
|
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
|
|
|
|
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.
|
|
|
|
*/
|
|
|
|
current_mc = S390_MACHINE_CLASS(
|
|
|
|
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
|
|
|
/* for "none" machine this results in true */
|
|
|
|
return get_machine_class()->ri_allowed;
|
|
|
|
}
|
|
|
|
|
|
|
|
bool cpu_model_allowed(void)
|
|
|
|
{
|
|
|
|
/* for "none" machine this results in true */
|
|
|
|
return get_machine_class()->cpu_model_allowed;
|
2016-09-07 13:50:40 +03:00
|
|
|
}
|
|
|
|
|
2016-03-29 17:18:47 +03:00
|
|
|
static char *machine_get_loadparm(Object *obj, Error **errp)
|
|
|
|
{
|
|
|
|
S390CcwMachineState *ms = S390_CCW_MACHINE(obj);
|
|
|
|
|
|
|
|
return g_memdup(ms->loadparm, sizeof(ms->loadparm));
|
|
|
|
}
|
|
|
|
|
|
|
|
static void machine_set_loadparm(Object *obj, const char *val, Error **errp)
|
|
|
|
{
|
|
|
|
S390CcwMachineState *ms = S390_CCW_MACHINE(obj);
|
|
|
|
int i;
|
|
|
|
|
|
|
|
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 */
|
|
|
|
}
|
|
|
|
}
|
2017-05-17 03:48:03 +03:00
|
|
|
static inline bool machine_get_squash_mcss(Object *obj, Error **errp)
|
|
|
|
{
|
|
|
|
S390CcwMachineState *ms = S390_CCW_MACHINE(obj);
|
|
|
|
|
|
|
|
return ms->s390_squash_mcss;
|
|
|
|
}
|
|
|
|
|
|
|
|
static inline void machine_set_squash_mcss(Object *obj, bool value,
|
|
|
|
Error **errp)
|
|
|
|
{
|
|
|
|
S390CcwMachineState *ms = S390_CCW_MACHINE(obj);
|
|
|
|
|
|
|
|
ms->s390_squash_mcss = value;
|
|
|
|
}
|
2016-03-29 17:18:47 +03:00
|
|
|
|
2015-03-12 15:53:51 +03:00
|
|
|
static inline void s390_machine_initfn(Object *obj)
|
|
|
|
{
|
|
|
|
object_property_add_bool(obj, "aes-key-wrap",
|
|
|
|
machine_get_aes_key_wrap,
|
|
|
|
machine_set_aes_key_wrap, NULL);
|
|
|
|
object_property_set_description(obj, "aes-key-wrap",
|
|
|
|
"enable/disable AES key wrapping using the CPACF wrapping key",
|
|
|
|
NULL);
|
|
|
|
object_property_set_bool(obj, true, "aes-key-wrap", NULL);
|
|
|
|
|
|
|
|
object_property_add_bool(obj, "dea-key-wrap",
|
|
|
|
machine_get_dea_key_wrap,
|
|
|
|
machine_set_dea_key_wrap, NULL);
|
|
|
|
object_property_set_description(obj, "dea-key-wrap",
|
|
|
|
"enable/disable DEA key wrapping using the CPACF wrapping key",
|
|
|
|
NULL);
|
|
|
|
object_property_set_bool(obj, true, "dea-key-wrap", NULL);
|
2016-03-29 17:18:47 +03:00
|
|
|
object_property_add_str(obj, "loadparm",
|
|
|
|
machine_get_loadparm, machine_set_loadparm, NULL);
|
|
|
|
object_property_set_description(obj, "loadparm",
|
|
|
|
"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,"
|
|
|
|
" and guest kernel",
|
|
|
|
NULL);
|
2017-05-17 03:48:03 +03:00
|
|
|
object_property_add_bool(obj, "s390-squash-mcss",
|
|
|
|
machine_get_squash_mcss,
|
|
|
|
machine_set_squash_mcss, NULL);
|
2017-12-06 17:44:38 +03:00
|
|
|
object_property_set_description(obj, "s390-squash-mcss", "(deprecated) "
|
2017-05-17 03:48:03 +03:00
|
|
|
"enable/disable squashing subchannels into the default css",
|
|
|
|
NULL);
|
|
|
|
object_property_set_bool(obj, false, "s390-squash-mcss", NULL);
|
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); \
|
|
|
|
mc->desc = "VirtIO-ccw based S390 machine v" verstr; \
|
|
|
|
if (latest) { \
|
|
|
|
mc->alias = "s390-ccw-virtio"; \
|
|
|
|
mc->is_default = 1; \
|
|
|
|
} \
|
|
|
|
} \
|
|
|
|
static void ccw_machine_##suffix##_instance_init(Object *obj) \
|
|
|
|
{ \
|
|
|
|
MachineState *machine = MACHINE(obj); \
|
2017-07-11 17:54:36 +03:00
|
|
|
current_mc = S390_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
|
|
|
|
2017-11-24 18:26:51 +03:00
|
|
|
#define CCW_COMPAT_2_11 \
|
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
|
|
|
HW_COMPAT_2_11 \
|
|
|
|
{\
|
|
|
|
.driver = TYPE_SCLP_EVENT_FACILITY,\
|
|
|
|
.property = "allow_all_mask_sizes",\
|
|
|
|
.value = "off",\
|
|
|
|
},
|
2017-11-24 18:26:51 +03:00
|
|
|
|
2017-08-10 15:07:31 +03:00
|
|
|
#define CCW_COMPAT_2_10 \
|
|
|
|
HW_COMPAT_2_10
|
|
|
|
|
2017-04-03 18:41:33 +03:00
|
|
|
#define CCW_COMPAT_2_9 \
|
2016-08-15 19:43:14 +03:00
|
|
|
HW_COMPAT_2_9 \
|
|
|
|
{\
|
|
|
|
.driver = TYPE_S390_STATTRIB,\
|
|
|
|
.property = "migration-enabled",\
|
|
|
|
.value = "off",\
|
|
|
|
},
|
2017-04-03 18:41:33 +03:00
|
|
|
|
2016-11-30 17:52:46 +03:00
|
|
|
#define CCW_COMPAT_2_8 \
|
2016-12-09 22:00:21 +03:00
|
|
|
HW_COMPAT_2_8 \
|
|
|
|
{\
|
|
|
|
.driver = TYPE_S390_FLIC_COMMON,\
|
|
|
|
.property = "adapter_routes_max_batch",\
|
|
|
|
.value = "64",\
|
|
|
|
},
|
2016-11-30 17:52:46 +03:00
|
|
|
|
2016-08-12 10:26:52 +03:00
|
|
|
#define CCW_COMPAT_2_7 \
|
|
|
|
HW_COMPAT_2_7
|
|
|
|
|
2016-04-25 11:37:23 +03:00
|
|
|
#define CCW_COMPAT_2_6 \
|
2015-07-13 15:04:36 +03:00
|
|
|
HW_COMPAT_2_6 \
|
|
|
|
{\
|
|
|
|
.driver = TYPE_S390_IPL,\
|
|
|
|
.property = "iplbext_migration",\
|
|
|
|
.value = "off",\
|
2016-07-11 13:55:44 +03:00
|
|
|
}, {\
|
|
|
|
.driver = TYPE_VIRTUAL_CSS_BRIDGE,\
|
|
|
|
.property = "css_dev_path",\
|
|
|
|
.value = "off",\
|
2015-07-13 15:04:36 +03:00
|
|
|
},
|
2016-04-25 11:37:23 +03:00
|
|
|
|
2015-12-23 22:42:11 +03:00
|
|
|
#define CCW_COMPAT_2_5 \
|
|
|
|
HW_COMPAT_2_5
|
|
|
|
|
2015-07-09 20:56:44 +03:00
|
|
|
#define CCW_COMPAT_2_4 \
|
2015-10-16 13:25:52 +03:00
|
|
|
HW_COMPAT_2_4 \
|
2015-07-09 20:56:44 +03:00
|
|
|
{\
|
|
|
|
.driver = TYPE_S390_SKEYS,\
|
|
|
|
.property = "migration-enabled",\
|
|
|
|
.value = "off",\
|
2015-09-11 16:16:44 +03:00
|
|
|
},{\
|
|
|
|
.driver = "virtio-blk-ccw",\
|
|
|
|
.property = "max_revision",\
|
|
|
|
.value = "0",\
|
|
|
|
},{\
|
|
|
|
.driver = "virtio-balloon-ccw",\
|
|
|
|
.property = "max_revision",\
|
|
|
|
.value = "0",\
|
|
|
|
},{\
|
|
|
|
.driver = "virtio-serial-ccw",\
|
|
|
|
.property = "max_revision",\
|
|
|
|
.value = "0",\
|
|
|
|
},{\
|
|
|
|
.driver = "virtio-9p-ccw",\
|
|
|
|
.property = "max_revision",\
|
|
|
|
.value = "0",\
|
|
|
|
},{\
|
|
|
|
.driver = "virtio-rng-ccw",\
|
|
|
|
.property = "max_revision",\
|
|
|
|
.value = "0",\
|
2015-10-08 16:11:34 +03:00
|
|
|
},{\
|
|
|
|
.driver = "virtio-net-ccw",\
|
|
|
|
.property = "max_revision",\
|
|
|
|
.value = "0",\
|
|
|
|
},{\
|
|
|
|
.driver = "virtio-scsi-ccw",\
|
|
|
|
.property = "max_revision",\
|
|
|
|
.value = "0",\
|
|
|
|
},{\
|
|
|
|
.driver = "vhost-scsi-ccw",\
|
|
|
|
.property = "max_revision",\
|
|
|
|
.value = "0",\
|
2015-07-09 20:56:44 +03:00
|
|
|
},
|
|
|
|
|
2017-11-24 18:26:51 +03:00
|
|
|
static void ccw_machine_2_12_instance_options(MachineState *machine)
|
|
|
|
{
|
|
|
|
}
|
|
|
|
|
|
|
|
static void ccw_machine_2_12_class_options(MachineClass *mc)
|
|
|
|
{
|
|
|
|
}
|
|
|
|
DEFINE_CCW_MACHINE(2_12, "2.12", true);
|
|
|
|
|
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)
|
|
|
|
{
|
2017-11-24 18:26:51 +03:00
|
|
|
ccw_machine_2_12_class_options(mc);
|
|
|
|
SET_MACHINE_COMPAT(mc, CCW_COMPAT_2_11);
|
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);
|
|
|
|
SET_MACHINE_COMPAT(mc, CCW_COMPAT_2_10);
|
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)
|
|
|
|
{
|
2017-07-11 17:54:37 +03:00
|
|
|
S390CcwMachineClass *s390mc = S390_MACHINE_CLASS(mc);
|
|
|
|
|
2017-04-03 18:41:33 +03:00
|
|
|
ccw_machine_2_10_class_options(mc);
|
|
|
|
SET_MACHINE_COMPAT(mc, CCW_COMPAT_2_9);
|
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)
|
|
|
|
{
|
2016-11-30 17:52:46 +03:00
|
|
|
ccw_machine_2_9_class_options(mc);
|
|
|
|
SET_MACHINE_COMPAT(mc, CCW_COMPAT_2_8);
|
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)
|
|
|
|
{
|
2016-09-07 13:50:40 +03:00
|
|
|
S390CcwMachineClass *s390mc = S390_MACHINE_CLASS(mc);
|
|
|
|
|
|
|
|
s390mc->cpu_model_allowed = false;
|
2016-08-12 10:26:52 +03:00
|
|
|
ccw_machine_2_8_class_options(mc);
|
|
|
|
SET_MACHINE_COMPAT(mc, CCW_COMPAT_2_7);
|
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
|
|
|
{
|
2016-03-09 15:11:17 +03:00
|
|
|
S390CcwMachineClass *s390mc = S390_MACHINE_CLASS(mc);
|
|
|
|
|
|
|
|
s390mc->ri_allowed = false;
|
2016-04-25 11:37:23 +03:00
|
|
|
ccw_machine_2_7_class_options(mc);
|
|
|
|
SET_MACHINE_COMPAT(mc, CCW_COMPAT_2_6);
|
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);
|
2016-03-03 14:48:34 +03:00
|
|
|
SET_MACHINE_COMPAT(mc, CCW_COMPAT_2_5);
|
|
|
|
}
|
|
|
|
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)
|
|
|
|
{
|
2016-04-25 11:37:23 +03:00
|
|
|
ccw_machine_2_5_class_options(mc);
|
2016-03-03 14:48:34 +03:00
|
|
|
SET_MACHINE_COMPAT(mc, CCW_COMPAT_2_4);
|
|
|
|
}
|
|
|
|
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)
|