[...] > @@ -0,0 +1,85 @@ > +/* > + * DIAGNOSE 0x318 functions for reset and migration > + * > + * Copyright IBM, Corp. 2019
Should be 2020 now. [...] > +static void s390_diag318_reset(DeviceState *dev) > +{ > + if (kvm_enabled()) > + kvm_s390_set_diag318_info(0); > +} > + > +static void s390_diag318_class_init(ObjectClass *klass, void *data) > +{ > + DeviceClass *dc = DEVICE_CLASS(klass); > + > + dc->reset = s390_diag318_reset; > + dc->vmsd = &vmstate_diag318; > + dc->hotpluggable = false; > + /* Reason: Created automatically during machine instantiation */ > + dc->user_creatable = false; > +} > + > +static const TypeInfo s390_diag318_info = { > + .class_init = s390_diag318_class_init, > + .parent = TYPE_DEVICE, > + .name = TYPE_S390_DIAG318, > + .instance_size = sizeof(DIAG318State), > +}; > + > +static void s390_diag318_register_types(void) > +{ > + type_register_static(&s390_diag318_info); > +} Do we really need a new device? Can't we simply glue that extended state to the machine state? -> target/s390x/machine.c > + > +type_init(s390_diag318_register_types) > diff --git a/hw/s390x/diag318.h b/hw/s390x/diag318.h > new file mode 100644 > index 0000000..06d9f67 > --- /dev/null > +++ b/hw/s390x/diag318.h > @@ -0,0 +1,40 @@ > +/* > + * DIAGNOSE 0x318 functions for reset and migration > + * > + * Copyright IBM, Corp. 2019 > + * > + * Authors: > + * Collin Walling <wall...@linux.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. > + */ > + > +#ifndef HW_DIAG318_H > +#define HW_DIAG318_H > + > +#include "qemu/osdep.h" > +#include "migration/vmstate.h" > +#include "qom/object.h" > +#include "hw/qdev-core.h" > + > +#define TYPE_S390_DIAG318 "diag318" > +#define DIAG318(obj) \ > + OBJECT_CHECK(DIAG318State, (obj), TYPE_S390_DIAG318) > + > +typedef struct DIAG318State { > + /*< private >*/ > + DeviceState parent_obj; > + > + /*< public >*/ > + uint64_t info; > +} DIAG318State; > + > +typedef struct DIAG318Class { > + /*< private >*/ > + DeviceClass parent_class; > + > + /*< public >*/ > +} DIAG318Class; > + > +#endif /* HW_DIAG318_H */ > \ No newline at end of file > diff --git a/hw/s390x/s390-virtio-ccw.c b/hw/s390x/s390-virtio-ccw.c > index e0e2813..d5b7a33 100644 > --- a/hw/s390x/s390-virtio-ccw.c > +++ b/hw/s390x/s390-virtio-ccw.c > @@ -41,6 +41,7 @@ > #include "hw/qdev-properties.h" > #include "hw/s390x/tod.h" > #include "sysemu/sysemu.h" > +#include "hw/s390x/diag318.h" > > S390CPU *s390_cpu_addr2state(uint16_t cpu_addr) > { > @@ -97,6 +98,7 @@ static const char *const reset_dev_types[] = { > "s390-sclp-event-facility", > "s390-flic", > "diag288", > + TYPE_S390_DIAG318, > }; > > static void subsystem_reset(void) > @@ -237,6 +239,17 @@ static void s390_create_sclpconsole(const char *type, > Chardev *chardev) > qdev_init_nofail(dev); > } > > +static void s390_init_diag318(void) > +{ > + Object *new = object_new(TYPE_S390_DIAG318); > + DeviceState *dev = DEVICE(new); > + > + object_property_add_child(qdev_get_machine(), TYPE_S390_DIAG318, > + new, NULL); > + object_unref(new); > + qdev_init_nofail(dev); > +} > + > static void ccw_init(MachineState *machine) > { > int ret; > @@ -294,6 +307,9 @@ static void ccw_init(MachineState *machine) > > /* init the TOD clock */ > s390_init_tod(); > + > + /* init object used for migrating diag318 info */ > + s390_init_diag318(); > } > > static void s390_cpu_plug(HotplugHandler *hotplug_dev, > @@ -566,6 +582,7 @@ static void machine_set_loadparm(Object *obj, const char > *val, Error **errp) > ms->loadparm[i] = ' '; /* pad right with spaces */ > } > } > + unrelated change. > static inline void s390_machine_initfn(Object *obj) > { > object_property_add_bool(obj, "aes-key-wrap", > diff --git a/hw/s390x/sclp.c b/hw/s390x/sclp.c > index f57ce7b..636348c 100644 > --- a/hw/s390x/sclp.c > +++ b/hw/s390x/sclp.c > @@ -15,6 +15,7 @@ > #include "qemu/osdep.h" > #include "qemu/units.h" > #include "qapi/error.h" > +#include "qemu/error-report.h" > #include "cpu.h" > #include "sysemu/sysemu.h" > #include "hw/boards.h" > @@ -22,6 +23,7 @@ > #include "hw/s390x/event-facility.h" > #include "hw/s390x/s390-pci-bus.h" > #include "hw/s390x/ipl.h" > +#include "kvm_s390x.h" > > static inline SCLPDevice *get_sclp_device(void) > { > @@ -37,10 +39,19 @@ static void prepare_cpu_entries(SCLPDevice *sclp, > CPUEntry *entry, int *count) > { > MachineState *ms = MACHINE(qdev_get_machine()); > uint8_t features[SCCB_CPU_FEATURE_LEN] = { 0 }; > + int max_entries; > int i; > > + /* Calculate the max number of CPU entries that can be stored in the > SCCB */ > + max_entries = (SCCB_SIZE - offsetof(ReadInfo, entries)) / > sizeof(CPUEntry); > + > s390_get_feat_block(S390_FEAT_TYPE_SCLP_CPU, features); > for (i = 0, *count = 0; i < ms->possible_cpus->len; i++) { > + if (*count == max_entries) { > + warn_report("Configuration only supports a max of %d CPU > entries.", > + max_entries); I remember that "the sclp response will be limited to 247 CPUs if the feature is one". So we should have a double layout and make max_entries depending on s390_has_feat(). Regarding the message, I'd probably do a "Due to the current CPU model, some CPUs might be hidden from the VM (SCLP)." A VM could still manually probe for others. Thanks! -- Thanks, David / dhildenb