summary refs log tree commit diff stats
path: root/hw
diff options
context:
space:
mode:
authorPeter Maydell <peter.maydell@linaro.org>2020-01-27 13:02:36 +0000
committerPeter Maydell <peter.maydell@linaro.org>2020-01-27 13:02:36 +0000
commit105b07f1ba462ec48b27e5cb74ddf81c6a79364c (patch)
treeb52e9840a334833a45da239ca8b6f9902f3217d6 /hw
parent760df0d121a836dcbf3726b80b820115aef21b30 (diff)
parent4103500e2fa934a6995e4cedab37423e606715bf (diff)
downloadfocaccia-qemu-105b07f1ba462ec48b27e5cb74ddf81c6a79364c.tar.gz
focaccia-qemu-105b07f1ba462ec48b27e5cb74ddf81c6a79364c.zip
Merge remote-tracking branch 'remotes/cohuck/tags/s390x-20200127' into staging
s390x changes:
- kvm: re-enable adapter interrupt suppression (AIS)
- fixes and cleanups

# gpg: Signature made Mon 27 Jan 2020 12:14:12 GMT
# gpg:                using RSA key C3D0D66DC3624FF6A8C018CEDECF6B93C6F02FAF
# gpg:                issuer "cohuck@redhat.com"
# gpg: Good signature from "Cornelia Huck <conny@cornelia-huck.de>" [marginal]
# gpg:                 aka "Cornelia Huck <huckc@linux.vnet.ibm.com>" [full]
# gpg:                 aka "Cornelia Huck <cornelia.huck@de.ibm.com>" [full]
# gpg:                 aka "Cornelia Huck <cohuck@kernel.org>" [marginal]
# gpg:                 aka "Cornelia Huck <cohuck@redhat.com>" [marginal]
# Primary key fingerprint: C3D0 D66D C362 4FF6 A8C0  18CE DECF 6B93 C6F0 2FAF

* remotes/cohuck/tags/s390x-20200127:
  s390x: sigp: Fix sense running reporting
  hw/s390x: Add a more verbose comment about get_machine_class() and the wrappers
  target/s390x: Remove DisasFields argument from extract_insn
  target/s390x: Move DisasFields into DisasContext
  target/s390x: Pass DisasContext to get_field and have_field
  target/s390x: Remove DisasFields argument from callbacks
  target/s390x: Move struct DisasFields definition earlier
  target/s390x/kvm: Enable adapter interruption suppression again
  docs/devel: fix stable process doc formatting
  target/s390x: Remove duplicated ifdef macro
  s390x/event-facility: fix error propagation
  s390x: adapter routes error handling
  s390x/event-facility.c: remove unneeded labels
  intc/s390_flic_kvm.c: remove unneeded label in kvm_flic_load()
  s390x/sclp.c: remove unneeded label in sclp_service_call()

Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
Diffstat (limited to 'hw')
-rw-r--r--hw/intc/s390_flic_kvm.c18
-rw-r--r--hw/s390x/event-facility.c35
-rw-r--r--hw/s390x/s390-virtio-ccw.c16
-rw-r--r--hw/s390x/sclp.c16
-rw-r--r--hw/s390x/virtio-ccw.c4
5 files changed, 46 insertions, 43 deletions
diff --git a/hw/intc/s390_flic_kvm.c b/hw/intc/s390_flic_kvm.c
index dddd33ea61..a306b26faa 100644
--- a/hw/intc/s390_flic_kvm.c
+++ b/hw/intc/s390_flic_kvm.c
@@ -331,6 +331,10 @@ static int kvm_s390_add_adapter_routes(S390FLICState *fs,
     int ret, i;
     uint64_t ind_offset = routes->adapter.ind_offset;
 
+    if (!kvm_gsi_routing_enabled()) {
+        return -ENOSYS;
+    }
+
     for (i = 0; i < routes->num_routes; i++) {
         ret = kvm_irqchip_add_adapter_route(kvm_state, &routes->adapter);
         if (ret < 0) {
@@ -358,6 +362,10 @@ static void kvm_s390_release_adapter_routes(S390FLICState *fs,
 {
     int i;
 
+    if (!kvm_gsi_routing_enabled()) {
+        return;
+    }
+
     for (i = 0; i < routes->num_routes; i++) {
         if (routes->gsi[i] >= 0) {
             kvm_irqchip_release_virq(kvm_state, routes->gsi[i]);
@@ -439,17 +447,14 @@ static int kvm_flic_load(QEMUFile *f, void *opaque, size_t size,
     count = qemu_get_be64(f);
     len = count * sizeof(struct kvm_s390_irq);
     if (count == FLIC_FAILED) {
-        r = -EINVAL;
-        goto out;
+        return -EINVAL;
     }
     if (count == 0) {
-        r = 0;
-        goto out;
+        return 0;
     }
     buf = g_try_malloc0(len);
     if (!buf) {
-        r = -ENOMEM;
-        goto out;
+        return -ENOMEM;
     }
 
     if (qemu_get_buffer(f, (uint8_t *) buf, len) != len) {
@@ -460,7 +465,6 @@ static int kvm_flic_load(QEMUFile *f, void *opaque, size_t size,
 
 out_free:
     g_free(buf);
-out:
     return r;
 }
 
diff --git a/hw/s390x/event-facility.c b/hw/s390x/event-facility.c
index 6afe278cad..9d6972afa8 100644
--- a/hw/s390x/event-facility.c
+++ b/hw/s390x/event-facility.c
@@ -182,11 +182,11 @@ static void write_event_data(SCLPEventFacility *ef, SCCB *sccb)
 {
     if (sccb->h.function_code != SCLP_FC_NORMAL_WRITE) {
         sccb->h.response_code = cpu_to_be16(SCLP_RC_INVALID_FUNCTION);
-        goto out;
+        return;
     }
     if (be16_to_cpu(sccb->h.length) < 8) {
         sccb->h.response_code = cpu_to_be16(SCLP_RC_INSUFFICIENT_SCCB_LENGTH);
-        goto out;
+        return;
     }
     /* first do a sanity check of the write events */
     sccb->h.response_code = cpu_to_be16(write_event_length_check(sccb));
@@ -196,9 +196,6 @@ static void write_event_data(SCLPEventFacility *ef, SCCB *sccb)
         sccb->h.response_code =
                 cpu_to_be16(handle_sccb_write_events(ef, sccb));
     }
-
-out:
-    return;
 }
 
 static uint16_t handle_sccb_read_events(SCLPEventFacility *ef, SCCB *sccb,
@@ -262,17 +259,18 @@ static void read_event_data(SCLPEventFacility *ef, SCCB *sccb)
 
     if (be16_to_cpu(sccb->h.length) != SCCB_SIZE) {
         sccb->h.response_code = cpu_to_be16(SCLP_RC_INSUFFICIENT_SCCB_LENGTH);
-        goto out;
+        return;
     }
 
-    sclp_cp_receive_mask = ef->receive_mask;
-
-    /* get active selection mask */
     switch (sccb->h.function_code) {
     case SCLP_UNCONDITIONAL_READ:
-        sclp_active_selection_mask = sclp_cp_receive_mask;
+        sccb->h.response_code = cpu_to_be16(
+            handle_sccb_read_events(ef, sccb, ef->receive_mask));
         break;
     case SCLP_SELECTIVE_READ:
+        /* get active selection mask */
+        sclp_cp_receive_mask = ef->receive_mask;
+
         copy_mask((uint8_t *)&sclp_active_selection_mask, (uint8_t *)&red->mask,
                   sizeof(sclp_active_selection_mask), ef->mask_length);
         sclp_active_selection_mask = be64_to_cpu(sclp_active_selection_mask);
@@ -280,18 +278,14 @@ static void read_event_data(SCLPEventFacility *ef, SCCB *sccb)
             (sclp_active_selection_mask & ~sclp_cp_receive_mask)) {
             sccb->h.response_code =
                     cpu_to_be16(SCLP_RC_INVALID_SELECTION_MASK);
-            goto out;
+        } else {
+            sccb->h.response_code = cpu_to_be16(
+                handle_sccb_read_events(ef, sccb, sclp_active_selection_mask));
         }
         break;
     default:
         sccb->h.response_code = cpu_to_be16(SCLP_RC_INVALID_FUNCTION);
-        goto out;
     }
-    sccb->h.response_code = cpu_to_be16(
-            handle_sccb_read_events(ef, sccb, sclp_active_selection_mask));
-
-out:
-    return;
 }
 
 static void write_event_mask(SCLPEventFacility *ef, SCCB *sccb)
@@ -303,7 +297,7 @@ static void write_event_mask(SCLPEventFacility *ef, SCCB *sccb)
     if (!mask_length || (mask_length > SCLP_EVENT_MASK_LEN_MAX) ||
         ((mask_length != 4) && !ef->allow_all_mask_sizes)) {
         sccb->h.response_code = cpu_to_be16(SCLP_RC_INVALID_MASK_LENGTH);
-        goto out;
+        return;
     }
 
     /*
@@ -328,9 +322,6 @@ static void write_event_mask(SCLPEventFacility *ef, SCCB *sccb)
 
     sccb->h.response_code = cpu_to_be16(SCLP_RC_NORMAL_COMPLETION);
     ef->mask_length = mask_length;
-
-out:
-    return;
 }
 
 /* qemu object creation and initialization functions */
@@ -347,7 +338,7 @@ static void sclp_events_bus_realize(BusState *bus, Error **errp)
         DeviceState *dev = kid->child;
 
         object_property_set_bool(OBJECT(dev), true, "realized", &err);
-        if (errp) {
+        if (err) {
             error_propagate(errp, err);
             return;
         }
diff --git a/hw/s390x/s390-virtio-ccw.c b/hw/s390x/s390-virtio-ccw.c
index e0e28139a2..e759eb5f83 100644
--- a/hw/s390x/s390-virtio-ccw.c
+++ b/hw/s390x/s390-virtio-ccw.c
@@ -505,6 +505,19 @@ static inline void machine_set_dea_key_wrap(Object *obj, bool value,
 
 static S390CcwMachineClass *current_mc;
 
+/*
+ * Get the class of the s390-ccw-virtio machine that is currently in use.
+ * Note: libvirt is using the "none" machine to probe for the features of the
+ * host CPU, so in case this is called with the "none" machine, the function
+ * returns the TYPE_S390_CCW_MACHINE base class. In this base class, all the
+ * various "*_allowed" variables are enabled, so that the *_allowed() wrappers
+ * below return the correct default value for the "none" machine.
+ *
+ * Attention! Do *not* add additional new wrappers for CPU features (e.g. like
+ * the ri_allowed() wrapper) via this mechanism anymore. CPU features should
+ * be handled via the CPU models, i.e. checking with cpu_model_allowed() during
+ * CPU initialization and s390_has_feat() later should be sufficient.
+ */
 static S390CcwMachineClass *get_machine_class(void)
 {
     if (unlikely(!current_mc)) {
@@ -521,19 +534,16 @@ static S390CcwMachineClass *get_machine_class(void)
 
 bool ri_allowed(void)
 {
-    /* 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;
 }
 
 bool hpage_1m_allowed(void)
 {
-    /* for "none" machine this results in true */
     return get_machine_class()->hpage_1m_allowed;
 }
 
diff --git a/hw/s390x/sclp.c b/hw/s390x/sclp.c
index f57ce7b739..af0bfbc2ec 100644
--- a/hw/s390x/sclp.c
+++ b/hw/s390x/sclp.c
@@ -197,24 +197,20 @@ int sclp_service_call(CPUS390XState *env, uint64_t sccb, uint32_t code)
 {
     SCLPDevice *sclp = get_sclp_device();
     SCLPDeviceClass *sclp_c = SCLP_GET_CLASS(sclp);
-    int r = 0;
     SCCB work_sccb;
 
     hwaddr sccb_len = sizeof(SCCB);
 
     /* first some basic checks on program checks */
     if (env->psw.mask & PSW_MASK_PSTATE) {
-        r = -PGM_PRIVILEGED;
-        goto out;
+        return -PGM_PRIVILEGED;
     }
     if (cpu_physical_memory_is_io(sccb)) {
-        r = -PGM_ADDRESSING;
-        goto out;
+        return -PGM_ADDRESSING;
     }
     if ((sccb & ~0x1fffUL) == 0 || (sccb & ~0x1fffUL) == env->psa
         || (sccb & ~0x7ffffff8UL) != 0) {
-        r = -PGM_SPECIFICATION;
-        goto out;
+        return -PGM_SPECIFICATION;
     }
 
     /*
@@ -226,8 +222,7 @@ int sclp_service_call(CPUS390XState *env, uint64_t sccb, uint32_t code)
 
     /* Valid sccb sizes */
     if (be16_to_cpu(work_sccb.h.length) < sizeof(SCCBHeader)) {
-        r = -PGM_SPECIFICATION;
-        goto out;
+        return -PGM_SPECIFICATION;
     }
 
     switch (code & SCLP_CMD_CODE_MASK) {
@@ -257,8 +252,7 @@ out_write:
 
     sclp_c->service_interrupt(sclp, sccb);
 
-out:
-    return r;
+    return 0;
 }
 
 static void service_interrupt(SCLPDevice *sclp, uint32_t sccb)
diff --git a/hw/s390x/virtio-ccw.c b/hw/s390x/virtio-ccw.c
index 6580ce5907..13f57e7b67 100644
--- a/hw/s390x/virtio-ccw.c
+++ b/hw/s390x/virtio-ccw.c
@@ -697,6 +697,7 @@ static void virtio_ccw_device_realize(VirtioCcwDevice *dev, Error **errp)
     CCWDeviceClass *ck = CCW_DEVICE_GET_CLASS(ccw_dev);
     SubchDev *sch;
     Error *err = NULL;
+    int i;
 
     sch = css_create_sch(ccw_dev->devno, errp);
     if (!sch) {
@@ -717,6 +718,9 @@ static void virtio_ccw_device_realize(VirtioCcwDevice *dev, Error **errp)
     ccw_dev->sch = sch;
     dev->indicators = NULL;
     dev->revision = -1;
+    for (i = 0; i < ADAPTER_ROUTES_MAX_GSI; i++) {
+        dev->routes.gsi[i] = -1;
+    }
     css_sch_build_virtual_schib(sch, 0, VIRTIO_CCW_CHPID_TYPE);
 
     trace_virtio_ccw_new_device(