aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--hw/s390x/css.c19
-rw-r--r--hw/s390x/virtio-ccw.c6
-rw-r--r--include/hw/s390x/ioinst.h1
-rw-r--r--pc-bios/s390-ccw/Makefile4
-rw-r--r--target/s390x/cpu_models.c10
-rw-r--r--target/s390x/cpu_models.h10
-rw-r--r--target/s390x/ioinst.c4
-rw-r--r--target/s390x/kvm.c1
8 files changed, 50 insertions, 5 deletions
diff --git a/hw/s390x/css.c b/hw/s390x/css.c
index 1e2f26b65a..599805d275 100644
--- a/hw/s390x/css.c
+++ b/hw/s390x/css.c
@@ -15,6 +15,7 @@
#include "hw/qdev.h"
#include "qemu/error-report.h"
#include "qemu/bitops.h"
+#include "qemu/error-report.h"
#include "exec/address-spaces.h"
#include "cpu.h"
#include "hw/s390x/ioinst.h"
@@ -432,6 +433,11 @@ static int css_interpret_ccw(SubchDev *sch, hwaddr ccw_addr,
return -EINVAL;
}
+ /* We don't support MIDA. */
+ if (ccw.flags & CCW_FLAG_MIDA) {
+ return -EINVAL;
+ }
+
if (ccw.flags & CCW_FLAG_SUSPEND) {
return suspend_allowed ? -EINPROGRESS : -EINVAL;
}
@@ -1800,13 +1806,26 @@ void subch_device_save(SubchDev *s, QEMUFile *f)
int subch_device_load(SubchDev *s, QEMUFile *f)
{
SubchDev *old_s;
+ Error *err = NULL;
uint16_t old_schid = s->schid;
+ uint16_t old_devno = s->devno;
int i;
s->cssid = qemu_get_byte(f);
s->ssid = qemu_get_byte(f);
s->schid = qemu_get_be16(f);
s->devno = qemu_get_be16(f);
+ if (s->devno != old_devno) {
+ /* Only possible if machine < 2.7 (no css_dev_path) */
+
+ error_setg(&err, "%x != %x", old_devno, s->devno);
+ error_append_hint(&err, "Devno mismatch, tried to load wrong section!"
+ " Likely reason: some sequences of plug and unplug"
+ " can break migration for machine versions prior to"
+ " 2.7 (known design flaw).\n");
+ error_report_err(err);
+ return -EINVAL;
+ }
/* Re-assign subch. */
if (old_schid != s->schid) {
old_s = channel_subsys.css[s->cssid]->sch_set[s->ssid]->sch[old_schid];
diff --git a/hw/s390x/virtio-ccw.c b/hw/s390x/virtio-ccw.c
index e6a6f74be3..90d37cb9ff 100644
--- a/hw/s390x/virtio-ccw.c
+++ b/hw/s390x/virtio-ccw.c
@@ -1279,9 +1279,13 @@ static int virtio_ccw_load_config(DeviceState *d, QEMUFile *f)
SubchDev *s = ccw_dev->sch;
VirtIODevice *vdev = virtio_ccw_get_vdev(s);
int len;
+ int ret;
s->driver_data = dev;
- subch_device_load(s, f);
+ ret = subch_device_load(s, f);
+ if (ret) {
+ return ret;
+ }
/* Re-fill subch_id after loading the subchannel states.*/
if (ck->refill_ids) {
ck->refill_ids(ccw_dev);
diff --git a/include/hw/s390x/ioinst.h b/include/hw/s390x/ioinst.h
index c559f53426..92d15655e4 100644
--- a/include/hw/s390x/ioinst.h
+++ b/include/hw/s390x/ioinst.h
@@ -182,6 +182,7 @@ typedef struct CCW1 {
#define CCW_FLAG_PCI 0x08
#define CCW_FLAG_IDA 0x04
#define CCW_FLAG_SUSPEND 0x02
+#define CCW_FLAG_MIDA 0x01
#define CCW_CMD_NOOP 0x03
#define CCW_CMD_BASIC_SENSE 0x04
diff --git a/pc-bios/s390-ccw/Makefile b/pc-bios/s390-ccw/Makefile
index 79a46b6735..fb88c13bc7 100644
--- a/pc-bios/s390-ccw/Makefile
+++ b/pc-bios/s390-ccw/Makefile
@@ -21,8 +21,10 @@ build-all: s390-ccw.img
s390-ccw.elf: $(OBJECTS)
$(call quiet-command,$(CC) $(LDFLAGS) -o $@ $(OBJECTS),"BUILD","$(TARGET_DIR)$@")
+STRIP ?= strip
+
s390-ccw.img: s390-ccw.elf
- $(call quiet-command,strip --strip-unneeded $< -o $@,"STRIP","$(TARGET_DIR)$@")
+ $(call quiet-command,$(STRIP) --strip-unneeded $< -o $@,"STRIP","$(TARGET_DIR)$@")
$(OBJECTS): Makefile
diff --git a/target/s390x/cpu_models.c b/target/s390x/cpu_models.c
index fc3cb25cc3..b34318f1e3 100644
--- a/target/s390x/cpu_models.c
+++ b/target/s390x/cpu_models.c
@@ -184,6 +184,7 @@ const S390CPUDef *s390_find_cpu_def(uint16_t type, uint8_t gen, uint8_t ec_ga,
S390FeatBitmap features)
{
const S390CPUDef *last_compatible = NULL;
+ const S390CPUDef *matching_cpu_type = NULL;
int i;
if (!gen) {
@@ -218,8 +219,16 @@ const S390CPUDef *s390_find_cpu_def(uint16_t type, uint8_t gen, uint8_t ec_ga,
if (def->type == type && def->ec_ga == ec_ga) {
return def;
}
+ /* remember if we've at least seen one with the same cpu type */
+ if (def->type == type) {
+ matching_cpu_type = def;
+ }
last_compatible = def;
}
+ /* prefer the model with the same cpu type, esp. don't take the BC for EC */
+ if (matching_cpu_type) {
+ return matching_cpu_type;
+ }
return last_compatible;
}
@@ -767,6 +776,7 @@ void s390_realize_cpu_model(CPUState *cs, Error **errp)
/* copy over properties that can vary */
cpu->model->lowest_ibc = max_model->lowest_ibc;
cpu->model->cpu_id = max_model->cpu_id;
+ cpu->model->cpu_id_format = max_model->cpu_id_format;
cpu->model->cpu_ver = max_model->cpu_ver;
check_consistency(cpu->model);
diff --git a/target/s390x/cpu_models.h b/target/s390x/cpu_models.h
index 136a602313..d41f8d6e38 100644
--- a/target/s390x/cpu_models.h
+++ b/target/s390x/cpu_models.h
@@ -46,6 +46,7 @@ typedef struct S390CPUModel {
/* values copied from the "host" model, can change during migration */
uint16_t lowest_ibc; /* lowest IBC that the hardware supports */
uint32_t cpu_id; /* CPU id */
+ uint8_t cpu_id_format; /* CPU id format bit */
uint8_t cpu_ver; /* CPU version, usually "ff" for kvm */
} S390CPUModel;
@@ -54,12 +55,14 @@ typedef struct S390CPUModel {
*
* bits 0-7: Zeroes (ff for kvm)
* bits 8-31: CPU ID (serial number)
- * bits 32-48: Machine type
- * bits 48-63: Zeroes
+ * bits 32-47: Machine type
+ * bit 48: CPU ID format
+ * bits 49-63: Zeroes
*/
#define cpuid_type(x) (((x) >> 16) & 0xffff)
#define cpuid_id(x) (((x) >> 32) & 0xffffff)
#define cpuid_ver(x) (((x) >> 56) & 0xff)
+#define cpuid_format(x) (((x) >> 15) & 0x1)
#define lowest_ibc(x) (((uint32_t)(x) >> 16) & 0xfff)
#define unblocked_ibc(x) ((uint32_t)(x) & 0xfff)
@@ -92,7 +95,8 @@ static inline uint64_t s390_cpuid_from_cpu_model(const S390CPUModel *model)
{
return ((uint64_t)model->cpu_ver << 56) |
((uint64_t)model->cpu_id << 32) |
- ((uint64_t)model->def->type << 16);
+ ((uint64_t)model->def->type << 16) |
+ (model->def->gen == 7 ? 0 : (uint64_t)model->cpu_id_format << 15);
}
S390CPUDef const *s390_find_cpu_def(uint16_t type, uint8_t gen, uint8_t ec_ga,
S390FeatBitmap features);
diff --git a/target/s390x/ioinst.c b/target/s390x/ioinst.c
index 62a777100c..d5e6b8066b 100644
--- a/target/s390x/ioinst.c
+++ b/target/s390x/ioinst.c
@@ -201,6 +201,10 @@ static int ioinst_orb_valid(ORB *orb)
(orb->ctrl1 & ORB_CTRL1_MASK_INVALID)) {
return 0;
}
+ /* We don't support MIDA. */
+ if (orb->ctrl1 & ORB_CTRL1_MASK_MIDAW) {
+ return 0;
+ }
if ((orb->cpa & HIGH_ORDER_BIT) != 0) {
return 0;
}
diff --git a/target/s390x/kvm.c b/target/s390x/kvm.c
index ba1e60f8a6..a3d00196f4 100644
--- a/target/s390x/kvm.c
+++ b/target/s390x/kvm.c
@@ -2580,6 +2580,7 @@ void kvm_s390_get_host_cpu_model(S390CPUModel *model, Error **errp)
unblocked_ibc = unblocked_ibc(prop.ibc);
}
model->cpu_id = cpuid_id(prop.cpuid);
+ model->cpu_id_format = cpuid_format(prop.cpuid);
model->cpu_ver = 0xff;
/* get supported cpu features indicated via STFL(E) */