aboutsummaryrefslogtreecommitdiff
path: root/hw
diff options
context:
space:
mode:
Diffstat (limited to 'hw')
-rw-r--r--hw/intc/s390_flic_kvm.c42
-rw-r--r--hw/s390x/css.c8
-rw-r--r--hw/s390x/s390-pci-bus.c7
-rw-r--r--hw/s390x/s390-virtio-ccw.c23
-rw-r--r--hw/s390x/s390-virtio.c6
-rw-r--r--hw/s390x/sclp.c42
6 files changed, 86 insertions, 42 deletions
diff --git a/hw/intc/s390_flic_kvm.c b/hw/intc/s390_flic_kvm.c
index fef808011f..21ac2e2dcd 100644
--- a/hw/intc/s390_flic_kvm.c
+++ b/hw/intc/s390_flic_kvm.c
@@ -280,12 +280,13 @@ static void kvm_s390_release_adapter_routes(S390FLICState *fs,
* kvm_flic_save - Save pending floating interrupts
* @f: QEMUFile containing migration state
* @opaque: pointer to flic device state
+ * @size: ignored
*
* Note: Pass buf and len to kernel. Start with one page and
* increase until buffer is sufficient or maxium size is
* reached
*/
-static void kvm_flic_save(QEMUFile *f, void *opaque)
+static void kvm_flic_save(QEMUFile *f, void *opaque, size_t size)
{
KVMS390FLICState *flic = opaque;
int len = FLIC_SAVE_INITIAL_SIZE;
@@ -324,24 +325,19 @@ static void kvm_flic_save(QEMUFile *f, void *opaque)
* kvm_flic_load - Load pending floating interrupts
* @f: QEMUFile containing migration state
* @opaque: pointer to flic device state
- * @version_id: version id for migration
+ * @size: ignored
*
* Returns: value of flic_enqueue_irqs, -EINVAL on error
* Note: Do nothing when no interrupts where stored
* in QEMUFile
*/
-static int kvm_flic_load(QEMUFile *f, void *opaque, int version_id)
+static int kvm_flic_load(QEMUFile *f, void *opaque, size_t size)
{
uint64_t len = 0;
uint64_t count = 0;
void *buf = NULL;
int r = 0;
- if (version_id != FLIC_SAVEVM_VERSION) {
- r = -EINVAL;
- goto out;
- }
-
flic_enable_pfault((struct KVMS390FLICState *) opaque);
count = qemu_get_be64(f);
@@ -372,6 +368,24 @@ out:
return r;
}
+static const VMStateDescription kvm_s390_flic_vmstate = {
+ .name = "s390-flic",
+ .version_id = FLIC_SAVEVM_VERSION,
+ .minimum_version_id = FLIC_SAVEVM_VERSION,
+ .fields = (VMStateField[]) {
+ {
+ .name = "irqs",
+ .info = &(const VMStateInfo) {
+ .name = "irqs",
+ .get = kvm_flic_load,
+ .put = kvm_flic_save,
+ },
+ .flags = VMS_SINGLE,
+ },
+ VMSTATE_END_OF_LIST()
+ }
+};
+
static void kvm_s390_flic_realize(DeviceState *dev, Error **errp)
{
KVMS390FLICState *flic_state = KVM_S390_FLIC(dev);
@@ -398,16 +412,6 @@ static void kvm_s390_flic_realize(DeviceState *dev, Error **errp)
flic_state->clear_io_supported = !ioctl(flic_state->fd,
KVM_HAS_DEVICE_ATTR, test_attr);
- /* Register savevm handler for floating interrupts */
- register_savevm(NULL, "s390-flic", 0, 1, kvm_flic_save,
- kvm_flic_load, (void *) flic_state);
-}
-
-static void kvm_s390_flic_unrealize(DeviceState *dev, Error **errp)
-{
- KVMS390FLICState *flic_state = KVM_S390_FLIC(dev);
-
- unregister_savevm(DEVICE(flic_state), "s390-flic", flic_state);
}
static void kvm_s390_flic_reset(DeviceState *dev)
@@ -438,7 +442,7 @@ static void kvm_s390_flic_class_init(ObjectClass *oc, void *data)
S390FLICStateClass *fsc = S390_FLIC_COMMON_CLASS(oc);
dc->realize = kvm_s390_flic_realize;
- dc->unrealize = kvm_s390_flic_unrealize;
+ dc->vmsd = &kvm_s390_flic_vmstate;
dc->reset = kvm_s390_flic_reset;
fsc->register_io_adapter = kvm_s390_register_io_adapter;
fsc->io_adapter_map = kvm_s390_io_adapter_map;
diff --git a/hw/s390x/css.c b/hw/s390x/css.c
index bb8e4be339..b0e81efc27 100644
--- a/hw/s390x/css.c
+++ b/hw/s390x/css.c
@@ -141,7 +141,8 @@ out_err:
int css_create_css_image(uint8_t cssid, bool default_image)
{
trace_css_new_image(cssid, default_image ? "(default)" : "");
- if (cssid > MAX_CSSID) {
+ /* 255 is reserved */
+ if (cssid == 255) {
return -EINVAL;
}
if (channel_subsys.css[cssid]) {
@@ -1267,7 +1268,7 @@ bool css_schid_final(int m, uint8_t cssid, uint8_t ssid, uint16_t schid)
uint8_t real_cssid;
real_cssid = (!m && (cssid == 0)) ? channel_subsys.default_cssid : cssid;
- if (real_cssid > MAX_CSSID || ssid > MAX_SSID ||
+ if (ssid > MAX_SSID ||
!channel_subsys.css[real_cssid] ||
!channel_subsys.css[real_cssid]->sch_set[ssid]) {
return true;
@@ -1282,9 +1283,6 @@ static int css_add_virtual_chpid(uint8_t cssid, uint8_t chpid, uint8_t type)
CssImage *css;
trace_css_chpid_add(cssid, chpid, type);
- if (cssid > MAX_CSSID) {
- return -EINVAL;
- }
css = channel_subsys.css[cssid];
if (!css) {
return -EINVAL;
diff --git a/hw/s390x/s390-pci-bus.c b/hw/s390x/s390-pci-bus.c
index 9c1c04e590..ac8f06d9e7 100644
--- a/hw/s390x/s390-pci-bus.c
+++ b/hw/s390x/s390-pci-bus.c
@@ -649,6 +649,7 @@ static void s390_pcihost_hot_plug(HotplugHandler *hotplug_dev,
pbdev = s390_pci_device_new(dev->id);
if (!pbdev) {
error_setg(errp, "create zpci device failed");
+ return;
}
}
@@ -717,11 +718,7 @@ static void s390_pcihost_hot_unplug(HotplugHandler *hotplug_dev,
break;
}
}
-
- if (!pbdev) {
- object_unparent(OBJECT(pci_dev));
- return;
- }
+ assert(pbdev != NULL);
} else if (object_dynamic_cast(OBJECT(dev), TYPE_S390_PCI_DEVICE)) {
pbdev = S390_PCI_DEVICE(dev);
pci_dev = pbdev->pdev;
diff --git a/hw/s390x/s390-virtio-ccw.c b/hw/s390x/s390-virtio-ccw.c
index 91d9cefbb5..a63b4e8c61 100644
--- a/hw/s390x/s390-virtio-ccw.c
+++ b/hw/s390x/s390-virtio-ccw.c
@@ -249,6 +249,11 @@ bool ri_allowed(void)
return s390mc->ri_allowed;
}
+ /*
+ * Make sure the "none" machine can have ri, otherwise it won't * be
+ * unlocked in KVM and therefore the host CPU model might be wrong.
+ */
+ return true;
}
return 0;
}
@@ -316,7 +321,11 @@ static const TypeInfo ccw_machine_info = {
} \
type_init(ccw_machine_register_##suffix)
+#define CCW_COMPAT_2_7 \
+ HW_COMPAT_2_7
+
#define CCW_COMPAT_2_6 \
+ CCW_COMPAT_2_7 \
HW_COMPAT_2_6 \
{\
.driver = TYPE_S390_IPL,\
@@ -372,14 +381,26 @@ static const TypeInfo ccw_machine_info = {
.value = "0",\
},
+static void ccw_machine_2_8_instance_options(MachineState *machine)
+{
+}
+
+static void ccw_machine_2_8_class_options(MachineClass *mc)
+{
+}
+DEFINE_CCW_MACHINE(2_8, "2.8", true);
+
static void ccw_machine_2_7_instance_options(MachineState *machine)
{
+ ccw_machine_2_8_instance_options(machine);
}
static void ccw_machine_2_7_class_options(MachineClass *mc)
{
+ ccw_machine_2_8_class_options(mc);
+ SET_MACHINE_COMPAT(mc, CCW_COMPAT_2_7);
}
-DEFINE_CCW_MACHINE(2_7, "2.7", true);
+DEFINE_CCW_MACHINE(2_7, "2.7", false);
static void ccw_machine_2_6_instance_options(MachineState *machine)
{
diff --git a/hw/s390x/s390-virtio.c b/hw/s390x/s390-virtio.c
index 544c61643d..0a963473ad 100644
--- a/hw/s390x/s390-virtio.c
+++ b/hw/s390x/s390-virtio.c
@@ -101,7 +101,11 @@ void s390_init_cpus(MachineState *machine)
gchar *name;
if (machine->cpu_model == NULL) {
- machine->cpu_model = "host";
+ if (kvm_enabled()) {
+ machine->cpu_model = "host";
+ } else {
+ machine->cpu_model = "qemu";
+ }
}
cpu_states = g_new0(S390CPU *, max_cpus);
diff --git a/hw/s390x/sclp.c b/hw/s390x/sclp.c
index fca37f511e..48e38b2bbe 100644
--- a/hw/s390x/sclp.c
+++ b/hw/s390x/sclp.c
@@ -26,7 +26,25 @@
static inline SCLPDevice *get_sclp_device(void)
{
- return SCLP(object_resolve_path_type("", TYPE_SCLP, NULL));
+ static SCLPDevice *sclp;
+
+ if (!sclp) {
+ sclp = SCLP(object_resolve_path_type("", TYPE_SCLP, NULL));
+ }
+ return sclp;
+}
+
+static void prepare_cpu_entries(SCLPDevice *sclp, CPUEntry *entry, int count)
+{
+ uint8_t features[SCCB_CPU_FEATURE_LEN] = { 0 };
+ int i;
+
+ s390_get_feat_block(S390_FEAT_TYPE_SCLP_CPU, features);
+ for (i = 0; i < count; i++) {
+ entry[i].address = i;
+ entry[i].type = 0;
+ memcpy(entry[i].features, features, sizeof(entry[i].features));
+ }
}
/* Provide information about the configuration, CPUs and storage */
@@ -37,7 +55,6 @@ static void read_SCP_info(SCLPDevice *sclp, SCCB *sccb)
sclpMemoryHotplugDev *mhd = get_sclp_memory_hotplug_dev();
CPUState *cpu;
int cpu_count = 0;
- int i = 0;
int rnsize, rnmax;
int slots = MIN(machine->ram_slots, s390_get_memslot_count(kvm_state));
@@ -50,10 +67,15 @@ static void read_SCP_info(SCLPDevice *sclp, SCCB *sccb)
read_info->offset_cpu = cpu_to_be16(offsetof(ReadInfo, entries));
read_info->highest_cpu = cpu_to_be16(max_cpus);
- for (i = 0; i < cpu_count; i++) {
- read_info->entries[i].address = i;
- read_info->entries[i].type = 0;
- }
+ read_info->ibc_val = cpu_to_be32(s390_get_ibc_val());
+
+ /* Configuration Characteristic (Extension) */
+ s390_get_feat_block(S390_FEAT_TYPE_SCLP_CONF_CHAR,
+ read_info->conf_char);
+ s390_get_feat_block(S390_FEAT_TYPE_SCLP_CONF_CHAR_EXT,
+ read_info->conf_char_ext);
+
+ prepare_cpu_entries(sclp, read_info->entries, cpu_count);
read_info->facilities = cpu_to_be64(SCLP_HAS_CPU_INFO |
SCLP_HAS_PCI_RECONFIG);
@@ -88,6 +110,8 @@ static void read_SCP_info(SCLPDevice *sclp, SCCB *sccb)
read_info->facilities |= cpu_to_be64(SCLP_FC_ASSIGN_ATTACH_READ_STOR);
}
+ read_info->mha_pow = s390_get_mha_pow();
+ read_info->hmfai = cpu_to_be32(s390_get_hmfai());
rnsize = 1 << (sclp->increment_size - 20);
if (rnsize <= 128) {
@@ -304,7 +328,6 @@ static void sclp_read_cpu_info(SCLPDevice *sclp, SCCB *sccb)
ReadCpuInfo *cpu_info = (ReadCpuInfo *) sccb;
CPUState *cpu;
int cpu_count = 0;
- int i = 0;
CPU_FOREACH(cpu) {
cpu_count++;
@@ -318,10 +341,7 @@ static void sclp_read_cpu_info(SCLPDevice *sclp, SCCB *sccb)
cpu_info->offset_standby = cpu_to_be16(cpu_info->offset_configured
+ cpu_info->nr_configured*sizeof(CPUEntry));
- for (i = 0; i < cpu_count; i++) {
- cpu_info->entries[i].address = i;
- cpu_info->entries[i].type = 0;
- }
+ prepare_cpu_entries(sclp, cpu_info->entries, cpu_count);
sccb->h.response_code = cpu_to_be16(SCLP_RC_NORMAL_READ_COMPLETION);
}