summary refs log tree commit diff stats
path: root/hw/s390x
diff options
context:
space:
mode:
Diffstat (limited to 'hw/s390x')
-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
5 files changed, 63 insertions, 23 deletions
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);
 }